In the following program, I have three different comments each after a line of code. Please read those comments to answer my questions.

# Property Critter
# Demonstrates get and set methods and properties

class Critter(object):
    """A virtual pet"""
    def __init__(self, name):
        print "A new critter has been born!"
        
        self.__name = name
        
        
    def get_name(self): #---------------------------------------reads a value to a private name?
        return self.__name
    
    
    def set_name(self, new_name): #-----------------------------set's a value to a private name?
        if new_name == "":
            print "A critter's name can't be the empty string."
        else:
            self.__name = new_name
            print "Name change successful."
            
    name = property(get_name, set_name) #----------------------allows access through dot notaion
    
    
    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.")

a little suggestion:

def set_name(self, new_name): #-----------------------------set's a value to a private name?
        if not new_name:
            raise ValueError, "A critter's name can't be the empty string."
        
        self.__name = new_name
        print "Name change successful."
try:
    crit.name = ""
except ValueError, e:
    print e

The class if functionally correct. A few things I'd like to suggest.

1) As far as I'm aware, protected names usually begin with one underscore.

self._name #"Correct"
self.__name #"Incorrect"

2) I'd probably put an underscore in front of "get_name" and "set_name" and use the property to handle attribute access.

3) Whenever I consider using the "==" comparison operator, I consider using "is".

if name is "":

is much clearer than

if name == "":

In fact, I'd probably import string earlier in the module and do this:

import string

if name is not in string.whitespace:

The python module string contains string constants that might be useful to you. It will be a great help to you if you know the python standard library, or are at least able to navigate it.

4) There is another syntax for a property involving class decorators. You don't need to understand how class decorators work at the moment, but you should be able to recognize that this:

@property
def name(self):
    return self._name

@name.setter
def name(self, value):
    self._name = value

is the same as:

def _get_name(self):
    return self._name

def _set_name(self, value):
    self._name = value

name = property(_get_name, _set_name)

It will be a great help to you if you know the python standard library, or are at least able to navigate it.

And in my opinion there is no better way to learn the python standard library than spending time in these forums answering and asking questions. Great code, lrh9. I learned something from you tonight.

Private attributes are always with "__" double underscore.

Taken directly from the zipfile module:

def _check_zipfile(fp):    #Begins with a single underscore. Protected function. Will not be returned by zipfile.__all__
    #...

def is_zipfile(filename):    #Public function. Will be returned by zipfile.__all__
    """Quickly see if a file is a ZIP file by checking the magic number.

    The filename argument may be a file or file-like object too.
    """
    #...

I commented on both functions to explain the difference. Special attributes and methods are wrapped in double underscores, but they're different.

In fact, the best way to describe it is that a public attribute or function does not begin with an underscore, a protected attribute or function does begin with an underscore, and a private attribute or function is wrapped in two underscores.

You all ready know what public means, but in object oriented programming protected means that only a class or subclass can access the attribute or method, and private means that only the class itself can access the attribute or method.

(Actually, in Python you can access attributes and methods wrapped in double underscores from outside the class, but double underscores always signify data or methods that are specific to the class object itself.)

class A:
    _a = 33

class B:
    __b = 22
    

a = A()
b = B()

print a._a
print b.__b

Output:

33
Traceback (most recent call last):
  File "p.py", line 12, in <module>
    print b.__b
AttributeError: B instance has no attribute '__b'

Using a leading double underscore on a class member makes it psuedo-private; however with persistence you can still see/access the object (it's just not immediately apparent). There is no such thing as "private" in Python.

>>> class A(object):
...     _Member_A = 'a'
...     __Member_B = 'b'
...     
>>> dir(A)
['_A__Member_B', '_Member_A', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> A._A__Member_B
'b'
>>>

As you can see, leading double underscored objects get obfuscated with the class name.

All though it is true that Python has no true protected and private attributes and methods, certain conventions indicate that a attribute or method should be protected or private.

programmersbook is right about the leading double underscore. I was wrong about it. I had only ever seen the double underscore used to wrap attributes and methods, but a leaded underscore does obfuscate the attribute or method. I was not aware of this property until now. Thank you for teaching me.

A more accurate statement would be that attributes or methods with a single leading underscore are protected, attributes or methods with a double leading underscore are private, and attributes or methods wrapped in double underscores are special.

This article has been dead for over six months. Start a new discussion instead.