tags:

views:

37

answers:

1

See example below. Using the _class_ prefix with the class instance 'object' gives the expected result. Why is the class variable even available at the class instance 'c()' without the _class_ prefix? In what situation is it used?

>>> class c:
        x=0


>>> c.x
0
>>> c().x
0
>>> c().__class__.x
0
>>> c.x += 1
>>> c.x
1
>>> c().x += 1
>>> c.x
1
>>> c().__class__.x += 1
>>> c.x
2
>>> 
+2  A: 

Why is the class variable even available at the class instance 'c()' without the class prefix?

You can usefully think of it as instances "inheriting from" their class. IOW, when an attribute named 'atr' is looked up on the instance x (e.g. by x.atr), unless found in the instance itself it's next looked up in the class (which in turn may cause lookup in the class's bases, up the mro chain).

In what situation is it used?

Most common single case:

class sic(object):
  def foo(self): ...

x = sic()
x.foo()

You may not think of foo as a "class variable", but that's because the term "variable" is really pretty meaningless in Python, which rather deals with names and attributes. There is no separate namespace for callable and non-callable objects at a given lexical scope: they all share the same namespace.

So, for example, if you did x.foo = 23 then you couldn't call x.foo() any more -- because the lookup for x.foo would give you the value 23, and that's an int, not callable.

Another way to look at this is that

class one(object):
  foo = lambda self: ...

class two(object):
  def foo(self): ...

class three(object):
  foo = 23

present no deep difference -- they're all way to set class attribute foo (one is not callable, two are; one is bound with a def statement, two with assignments; there differences are not deep in terms of attribute lookup on instances of these classes).

A typical use for non-callable attributes might be:

class zap(zop):
  zep = None

  def blub(self):
    if self.zep is None: self.zep = 23
  ...&c...

No need to give zap an __init__ with self.zep = None and a delegation to the superclass's __init__ (if any) -- simpler to just inherit zop's __init__ (if any) and use a class attribute as long as feasible (it will become an instance attribute instead if and only if blub is called on that instance -- also may save a tiny bit of memory for instances on which blub is never called;-).

Alex Martelli
Thanks for the detailed response. Can you pl explain the discrepancy in this example, why is the class variable and instance variable same in this situation: >>> class c: x=[1] >>> c.x [1] >>> c().x.append(2) >>> c.x [1, 2] >>> Edit: The code does not show formatted, but the idea is to use a list instead of integer
@tx10: It's best to ask a new question for this. As you found, it is difficult to display code correctly in a comment, whether it is a question or an answer.
Mark Tolonen
@tx10, 100% agreement with @Mark. Anyway, binding a barename (e.g. by assignment, or `def`) and calling a mutating method (such as the `append` in your example) are such totally, completely, utterly, and intrinsically different, distinct, separate and disjoint issues, that it's hard to see why anybody would expect them to have the same behavior (though apparently many Python beginners do).
Alex Martelli