Confused about properties, descriptors, and attributes...

Fredrik Lundh fredrik at pythonware.com
Thu Apr 20 17:37:18 EDT 2006


redefined.horizons at gmail.com wrote:

> But what is the difference between an Attribute of a Class, a
> Descriptor in a Class, and a Property in a Class?

A class has a class dictionary, which contains methods and other
class-level members for this class.

Each instance of a class has its own instance dictionary, which holds
the attributes for that instance.

An attribute is an instance variable that lives in the instance dictionary.
if you ask for the attribute value, you get the value from the instance
dictionary.  If the attribute is not found in the instance, Python looks
in the class dictionary.  If you assign to an attribute, Python adds it
to the instance dictionary.

A descriptor is a special kind of class attribute that implements a
descriptor protocol.  if you ask for the attribute value for a descriptor
attribute, or assign to it, Python will ask the descriptor object what
to do.

A property is simply a ready-made descriptor type that maps attribute
access to getter and setter methods.

Still with me?

> If I had a Monster Class, and I wanted to give each Monster a member
> variable called ScaryFactor, how would I define it?

Assign to it in the initialization method:

    class Monster(object):
        def __init__(self):
            self.ScaryFactor = 100

This gives all monsters their own ScaryFactor value.

Since Python will look in the class dictionary if an attribute is not found
in the instance dictionary, you can also do:

    class AltMonster(object):
        ScaryFactor = 100

If you do this, all monsters will share the same factor value.  However,
if you set the factor on the instance (either by assigning to self inside
a method, or by assigning to it from the outside), that object will get
its own copy.

    m1 = AltMonster()
    m2 = AltMonster()
    m3 = AltMonster()
    print m1.ScaryFactor, m2.ScaryFactor, m3.ScaryFactor
    # prints 100, 100, 100 (all three refers to the same object)

    m1.ScaryFactor = 200
    print m1.ScaryFactor, m2.ScaryFactor, m3.ScaryFactor
    # prints 200, 100, 100 (m1 has its own attribute value)

    Monster.ScaryFactor = 300 # update the class attribute
    print m1.ScaryFactor, m2.ScaryFactor, m3.ScaryFactor
    # prints 200, 300, 300 (!)

> Does a Property simply provide methods that access an Attribute?

It maps attribute accesses to method calls, yes.

You can use it instead of a plain attribute when you need to add getter
or setter logic; there's usually no reason to use properties instead of
attributes for plain data members.

To learn more about descriptors (which are really simple, and rather mind-
boggling), see

    http://users.rcn.com/python/download/Descriptor.htm

Hope this helps!

</F>






More information about the Python-list mailing list