[program-l] Re: Python, any way to return values when using the cmd module without using Globals?

  • From: "Homme, James" <james.homme@xxxxxxxxxxxx>
  • To: "program-l@xxxxxxxxxxxxx" <program-l@xxxxxxxxxxxxx>
  • Date: Fri, 26 Oct 2012 11:29:54 +0000

Hi Al,
Probably because I'm also trying to wrap my head around this stuff, I'm not 
getting what you are saying. I'm not totally sure of exactly the best way to 
code this, but I'm thinking that in the class you are writing, you would want 
to have two functions for each thing that you want to update and read. I'm 
going to paste a couple of book exerpts below. The book is Python Programming 
For The Absolute Beginner. Maybe it will sink in with me, too.

Using Private Attributes and PrivateMethods

By default, all of an objectâs attributes and methods are public,
 meaning that they can be directly accessed or invoked by a client. To 
encourage encapsulation, you can define an attribute or method as private,
 meaning that only other methods of the object itself can easily access or 
invoke them.

Introducing the Private Critter Program

The Private Critter program instantiates an object with both private and public 
attributes and methods.
Figure 8.8
 shows a sample run.

Figure 8.8.  The objectâs private attribute and private method are indirectly 
accessed.

Creating Private Attributes

To limit the direct access of object attributes by clients, you can use private 
attributes. In the constructor method, I create two attributes, one public
and one private:

# Private Critter
# Demonstrates private variables and methods
# Michael Dawson - 3/25/03

class Critter(object):
    âââA virtual petâââ
    def __init__(self, name, mood):
        print âA new critter has been born!â
        self.name = name             # public attribute
        self.__mood = mood           # private attribute

The two underscore characters that begin the second attribute name tell Python 
that this is a private attribute. To create a private attribute of your own,
just begin the attribute name with two underscores.

Accessing Private Attributes

Itâs perfectly fine to access an objectâs private attribute inside the class 
definition of the object. (Remember, private attributes are meant to discourage
client code from directly accessing the attribute.) I access a private 
attribute in the talk() method:

def talk(self):
    print â\nIâmâ, self.name
    print âRight now I feelâ, self.__mood, â\nâ

This method prints the value of the objectâs private attribute, which 
represents a critterâs mood.

If I tried to access this attribute outside of the Critter
 class definition, Iâd have trouble. Hereâs an interactive session to show you 
what I mean:

>>> crit = Critter(name = âPoochieâ, mood = âhappyâ)
A new critter has been born!
>>> print crit.mood
Traceback (most recent call last):
  File â<pyshell#2>â, line 1, in ?
    print crit.mood
AttributeError: âCritterâ object has no attribute âmoodâ

By raising an AttributeError exception, Python is saying that crit has no 
attribute mood
. If you think you can outsmart Python by adding the two leading underscores, 
youâd be wrong. Thatâs just what I tried in the next part of my interactive
session:

>>> print crit.__mood
Traceback (most recent call last):
  File â<pyshell#3>â, line 1, in ?
    print crit.__mood
AttributeError: âCritterâ object has no attribute â__moodâ

This also raises an AttributeError
 exception. Python is again saying that the attribute doesnât exist. So does 
this mean that the value of a private attribute is completely inaccessible
outside of its class definition? Well, no. Python hides the attribute through a 
special naming convention, though itâs still technically possible to access
the attribute. Thatâs what I did in the next part of my interactive session:

>>> print crit._Critter__mood
happy

This line prints the value of the elusive private attribute, which in this case 
is the string âhappyâ.

Since itâs possible to access private attributes, you may be thinking: What 
good are they? Well, defining an attribute or method as private is not about
completely preventing access. Rather, itâs about preventing inadvertent access. 
It says that a particular attribute or method is meant only for an objectâs
internal use. So, you should never try to directly access the private 
attributes or methods of an object from outside of its class definition.

Creating Private Methods

You can create a private method in the same, simple way you create a private 
attribute: by adding two leading underscores to its name. Thatâs just what
I do in the next method definition in the class:

def __private_method(self):
    print âThis is a private method.â

This is a private method but can easily be accessed by any other method in the 
class. Like private attributes, private methods are meant only to be accessed
by an objectâs own methods.

Accessing Private Methods

Just as with private attributes, accessing an objectâs private methods within 
its class definition is simple. In the public_method() method, I access the
classâ private method:

def public_method(self):
    print âThis is a public method.â
    self.__private_method()

This method prints the string âThis is a public method.â and then invokes the 
objectâs private method.

Like private attributes, private methods arenât meant to be directly accessed 
by clients. Back in my interactive session, I try to access critâs private
method:

>>> crit.private_method()
Traceback (most recent call last):
  File â<pyshell#6>â, line 1, in ?
    crit.private_method()
AttributeError: âCritterâ object has no attribute âprivate_methodâ

This attempt raises the familiar AttributeError exception. Python is saying 
that crit
 has no method with this name. Python hides the method through the same, 
special naming convention. If I try again by adding the two leading underscores
to the method name, I run into the same error message:

>>> crit.__private_method()
Traceback (most recent call last):
  File â<pyshell#7>â, line 1, in ?
    crit.__private_method()
AttributeError: âCritterâ object has no attribute â__private_methodâ

However, just as with private attributes, it is technically possible to access 
private methods from anywhere in a program. Hereâs the final part of my 
interactive
session as proof:

>>> crit._Critter__private_method()
This is a private method.

But, as you probably know by now, a client should never attempt to directly 
access an objectâs private methods.

Respecting an Objectâs Privacy

In the main part of the program, I behave myself and donât go prodding into an 
objectâs private attributes or methods. Instead, I create an object and invoke
its two public methods:

# main
crit = Critter(name = âPoochieâ, mood = âhappyâ)
crit.talk()
crit.public_method()

raw_input(â\n\nPress the enter key to exit.â)

critâstalk()
 method announces to the world how the critter is feeling. critâs 
public_method() method prints the string âThis is a public method.â and then 
invokes critâs
 private method, which prints the string âThis is a private method.â Finally, 
the program ends.

Understanding When to Implement Privacy

So now that you know how to use privacy, should you make every attribute in 
every class private to protect them from the evil, outside world? Well, no.
Privacy is like a fine spice: used sparingly, it can greatly improve what 
youâre making. Make private any method you donât want a client to invoke. If
itâs critical that an attribute never be directly accessed by a client, you can 
make it private. But keep this to a minimum, as creating private attributes
is rare in Python. The philosophy among programmers is to trust that clients 
will use an objectâs methods and not directly alter its attributes.

NOTE

 When you write a class:

â  Create methods so that clients wonât need to directly access an 
objectâsattributes.

â  Use privacy sparingly and only for those few attributes and methods that are
completely internal to the operation of objects.

When you use an object:

â  Minimize the direct reading of an objectâs attributes.

â Avoid directly altering an objectâs attributes.

â  Never directly access an objectâs private attributes or methods.

Controlling Attribute Access

Sometimes, instead of denying access to an attribute, you may want only to 
limit access to it. For example, you might have an attribute that you want 
client
code to be able to read, but not change. Python provides a few tools to 
accomplish this kind of thing, including properties
. Properties allow you to manage exactly how an attribute is accessed or 
changed.

Introducing the Property Critter

The Property Critter program allows client code to read a Critter
 objectâs attribute that refers to its name, but imposes restrictions when 
client code attempts to change the attributeâs value. If client code tries to
assign the attribute the empty string, the program complains and does not allow 
the change.
Figure 8.9
 shows the results of the program.

Figure 8.9.  A property controls access to the Critterobjectâs attribute for 
its name.

Using Get Methods

One way to control access to an attribute is to create access methods
âmethods that allow indirect access to attributes and often impose some sort of 
restriction on that access. One type of access method is a get method,
 which gets the value of an attribute. By convention, a get methodâs name 
always starts with the word âget.â I wrote the simplest form of a get method for
the private attribute __name, called get_name()
. The method simply returns the value of the private attribute, which 
represents a critterâs name.

# Property Critter
# Demonstrates get and set methods and properties
# Michael Dawson - 3/26/03

class Critter(object):
    âââA virtual petâââ
    def __init__(self, name):
        print âA new critter has been born!â
        self.__name = name

    def get_name(self):
        return self.__name

Now, itâs easy to get the value of the private attribute through the get method 
as you can see in this interactive session:

>>> crit = Critter(âPoochieâ)
>>> print crit.get_name()
Poochie

By creating a get method, you can provide read access to a private attribute.

Using Set Methods

Since I want to allow controlled changes to the name of a critter, I created 
another type of access method, called a set method
, which sets an attribute to a value. By convention, a set methodâs name always 
starts with the word âset.â This new method, set_name()
, allows a value to be assigned to the private variable __name
; however, it imposes the restriction that the value cannot be the empty string.

def set_name(self, new_name):
    if new_name == ââ:
        print âA critterâs name canât be the empty string.â
    else:
        self.__name = new_name
        print âName change successful.â

If I try to change the name of my critter to the empty string, set_name() wonât 
let me:

>>> crit.set_name(ââ)
A critterâs name canât be the empty string.

However, the method will allow me to set the name to anything else:

>>> crit.set_name(âRandolphâ)
Name change successful.
>>> print crit.get_name()
Randolph

Using Properties

Properties allow you to harness the power of access methods while hiding the 
implementation from the client. A property essentially wraps access methods
around the consistent and familiar dot notation.

NOTE

 Properties only work as intended with new-style classes. If you must work 
withold-style classes, you can control attribute access with the special 
methods__getattr__()and__setattr__().
You can find out about these methodsthrough the online Python documentation at
http://www.python.org/doc.

I use the property()
 function to create a property in the next line of the program:

name = property(get_name, set_name)

This code creates a property called name
 that allows indirect access to the private attribute __name through the 
get_name() and set_name()
 methods. Notice that the arguments of the property()
 function are the names of the methods, not calls to the methods, so they donât 
include parentheses.

To create a property, follow my example. Supply the property()
 function with get and set methods to allow controlled access to a private 
attribute. (You can supply just a get method to create a read-only property.)
 Finally, make sure to assign the resulting property to an attribute name which 
client code will use to access the property.

By using the new name
 property, I can get the name of my critter through the familiar dot notation 
as you can see in the beginning of this interactive session:

>>> print crit.name
Randolph

This line of code invokes the get_name()
 method. It has the same effect as the line
print get_name(), but it maintains the consistent dot notation format.

I can also set the name of my critter through dot notation:

>>> crit.name = âSammyâ
Name change successful.
>>> print crit.name
Sammy

This first line of code indirectly invokes the set_name()
 method. It has the same effect as the line set_name(âSammyâ)
, but it maintains the consistent dot notation format.

As before, if I try to make my critterâs name the empty string, I canât:

>>> crit.name = ââ
A critterâs name canât be the empty string.

The rest of the Property Critter program uses the name
 property to indirectly access the private __name attribute:

def talk(self):
    print â\nHi, Iâmâ, self.name
# main
crit = Critter(âPoochieâ)
crit.talk()
print â\nMy critterâs name is:â,
print crit.name
print â\nAttempting to change my critterâs name.â
crit.name = ââ
print â\nAttempting to change my critterâs name again.â
crit.name = âRandolphâ

crit.talk()

raw_input(â\n\nPress the enter key to exit.â)

As you can see, I access the name
 property in the talk() method of the Critter
 class the same way I access it in the main part of the program, through dot 
notation. You access a property the same way, whether youâre in the class 
definition
of the property or in some other part of the program.

-----Original Message-----
From: program-l-bounce@xxxxxxxxxxxxx [mailto:program-l-bounce@xxxxxxxxxxxxx] On 
Behalf Of Al Puzzuoli
Sent: Thursday, October 25, 2012 10:14 PM
To: Program L
Subject: [program-l] Python, any way to return values when using the cmd module 
without using Globals?

First of all, many thanks to everyone who is helping  me along my path by 
ansering countless questions on this list. I am resolving issues, learning a 
bit more every day. Of course, the more I learn, the more I realize I don't 
know.
My latest issue yet again has to do with the cmd module. The problem is that I 
was hoping to use it to implement for example, a method called do_new ().
Do_new would prompt for a ticker symbol, read the data into a Pandas DataFrame, 
and then return the DataFrame. However, cmd's methods apparently don't return 
values other than success or failure codes. I can make this work if I declare 
my DataFrame as a global variable but of course, I assume there must be a 
better way?
Thanks,

Al

** To leave the list, click on the immediately-following link:-
** [mailto:program-l-request@xxxxxxxxxxxxx?subject=unsubscribe]
** If this link doesn't work then send a message to:
** program-l-request@xxxxxxxxxxxxx
** and in the Subject line type
** unsubscribe
** For other list commands such as vacation mode, click on the
** immediately-following link:-
** [mailto:program-l-request@xxxxxxxxxxxxx?subject=faq]
** or send a message, to
** program-l-request@xxxxxxxxxxxxx with the Subject:- faq

________________________________

This e-mail and any attachments to it are confidential and are intended solely 
for use of the individual or entity to whom they are addressed. If you have 
received this e-mail in error, please notify the sender immediately and then 
delete it. If you are not the intended recipient, you must not keep, use, 
disclose, copy or distribute this e-mail without the author's prior permission. 
The views expressed in this e-mail message do not necessarily represent the 
views of Highmark Inc., its subsidiaries, or affiliates.
Nï^jïïïïbïï%ïï(ïï^ïiïv&ïz\ïïYhï)ïï)äïïïkï
ÚZÞçïïzXïïï+ïËïï-

Other related posts: