Class Variable Access and Assignment

Magnus Lycka lycka at carmen.se
Fri Nov 4 16:21:07 CET 2005


Graham wrote:
> My question remains however, i suppose i'm not familiar with how this
> functions in
> other languages, but what is the common way of referring to a class
> variable.
> 
> is <class>.<var> the norm?
> or <instance>.<var> the norm.

It's not always that easy, due to inheritance. You might want
the <var> defined in the class where a method you define now
is implemented (A.<var> if we're in a method defined in class A),
or you might want <var> in the class of the instance object
(which could be a subclass of A). You can get that through
self.__class__.<var>, so I guess you could always manage without
Python searching in the class scope after searching the instance
scope, if it wasn't for the problem below...

> I just seems to me that <instance>.<var> shouldn't defer to the class
> variable if
> an instance variable of the same name does not exists, it should, at
> least how i
> understand it raise an exception.

So, you want this:

 >>> class A:
...     def f(self):
...         print 'Hello'
...
 >>> a = A()
 >>> a.f()
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
AttributeError: A instance has no attribute 'f'

A bit boring that we need to make method calls
with a.__class__.f(a) in your Python...

Python is more consistent than you have thought...
You know, it could be that we want to assign the
method to another variable, as in:

o = A()
o_f = o.f # This might look as I'm getting a normal
           # attribute, but f is a method
for i in range(gazillion):
     o_f() # This is slightly faster than o.f()

Or, we might want to do:
o.f=len
o.f('Hello')

Here, o.f is no longer a method in o's class hierarchy, but
it's still callable.

If you think about it, you'll understand that in such a dynamic
language as Python, there is no way that the interpreter can
know before lookup whether it will find a method or a simple
attribute. If it's going to look in different places depending
on what it will find when it has looked...we have a Catch 22.

Normal methods in Python are defined in the scope of the class,
and they are passed the instance object as their first argument
when they are called. The call (where the instance object is
implicitly called in case of a bound method) is something that
comes after the lookup, as you can see in the a_f() example.

Python is *very* dynamic. The behaviour of the class can change
after the instance has been created.

 >>> class A:
...     def f(self):
...         print 'Hello'
...
 >>> a = A()
 >>> a.f()
Hello
 >>> del A.f
 >>> a.f()
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
AttributeError: A instance has no attribute 'f'

How would this work if 'a.f' doesn't cause a lookup in A if it's
missing in a? Do you want a.f to first search the instance a, then
the class A, and if it finds f in A, issue an AttributeError if it
turns out that f isn't a method?



More information about the Python-list mailing list