Static Data?

Peter Otten __peter__ at web.de
Sun Apr 11 10:16:19 CEST 2004


Stevie_mac wrote:

> In Jeffs solution, Is self._ID the same variable as _ID (declared
> immediately after class Counted). Is there 3 _IDs? If you have the time,

Jeff Epler's code with annotations:

class Counted:
    _ID = 0 # set the class attribute; same as Counted._ID = 0

    def __init__(self):
        Counted._ID += 1 # increment the class attribute
        self._ID = Counted._ID # set the instance attribute to the 
                               # current value of the class attribute

> could you explain (nothing fancy, just brief) the meaning of declaring
> variables in different
> locations (like self, below class, as part of class, in a class def). 
> This would be greatly appreciated.
> 
> and Peters solution
> class Object:
>     _ID = 1
>     def __init__(self):
>         self.ID = Object._ID
>         Object._ID += 1
> Is Object._ID a class instance variable and self.ID a 'shared' class
> variable

This is basically the same as Jeff's. I just chose different names for the
class attribute (_ID) and instance attribute (ID).

If you set an attribute in the class,

class Object:
    clsattr = 1

that is the same as

class Object:
    pass
Object.clsattr = 1

If you set an instance attribute you always need the instance:

inst = Object()
inst.attr = 2

Inside a method it's the same, only the instance will most likely be named
self.

class Object:
    def method(self, newvalue):
        self.attr = newvalue

Now for attribute lookup:

inst.attr

will first look up attr in the instance, and if it's not there, it will fall
back to the class:

>>> class Object:
...     pass
...
>>> Object.attr = "in class"
>>> inst = Object()
>>> inst.attr
'in class'
>>> inst.attr = "in instance"
>>> inst.attr
'in instance'

The class attribute is still there, only "shaded" bye the instance
attribute:

>>> Object.attr
'in class'

Now let's delete the instance attribute:

>>> del inst.attr
>>> inst.attr
'in class'

The class attribute becomes visible again.

Once you have understood the above, classmethods are just a another way to
access the class instead of the instance. The advantage over an explicit
use of the class identifier is that with inheritance they always provide
the actual class: 

>>> class Object(object):
...     def method(cls):
...             print cls.__name__
...     method = classmethod(method)
...
>>> class Sub(Object):
...     pass
...
>>> Object().method()
Object
>>> Sub().method()
Sub

Peter




More information about the Python-list mailing list