staticmethod problems

Shalabh Chaturvedi shalabh at cafepy.com
Thu Aug 19 15:56:55 EDT 2004


Neil Zanella wrote:
> Hello,
> 
> Coming from C++ and Java, one of the surprising things about Python is that
> not only class instances (AKA instance objects) but also classes themselves
> are objects in Python.

You'll soon be surprised again - at how you managed to live without this 
feature <wink>.

> 
> This means that variabls such as x and y appearing inside class statements
> in Python essentially behave like static class variables in other languages.
> On the other hand a variable is specified as an instance variable as self.x
> and self.y inside a class in Python. Unqualified variables appearing inside
> the class are class variables and not instance variables.

Yes, but unqualified variables appearing *inside methods* are not looked 
up in the class (or any other object).

class C:
    x = 1

    def f(self):
        # different ways to access the x above
        print self.x
        print self.__class__.x
        print C.x

        # incorrect way to access x (raises exception)
        print x

        # unqualified variables here have to be found
        # in specific namespaces like locals or globals etc.
        # note that self is a local.

> So now what I would like to do, is access the static variable of a superclass
> object from a subclass object from a static method in the subclass object.
> 
> Here is what is not clear to me:
> Why don't the commentd out lines below work? I was
> expecting that a polymorphic search taking place when I
> call Y.foo() would find both x and y, but this did not happen.
> In particular, why does python force me to write something
> like I write in foo3() to enforce the behavior I want in foo()?
> 
> 
> Thanks,
> 
> Neil
> 
> #!/usr/bin/python
> 
> class X:
>   x = 10
> 
> class Y(X):
>   y = 5
>   def foo():
>     print x + y
>   foo = staticmethod(foo)
>   def foo2():
>     print X.x + y
>   foo2 = staticmethod(foo2)
>   def foo3():
>     print X.x + Y.y
>   foo3= staticmethod(foo3)
> 
> #Y.foo() # I was expecting the same behavior as below,
>          # with the value 15 printed. Why is this not
>          # working (and where can I find more about
>          # staticmethod)?

Since x and y are not defined in the method, nor are globals or 
builtins. You always have to start with an object in one of these 
namespaces and work your way to the object you want.

> #Y.foo2() # doesn't work either. Why?
> 
> Y.foo3() # works

You might want to try classmethod instead. When you're inside a 
staticmethod, you have no idea which class you're in. But classmethods 
get the class as the first argument. And so you can use somewhat similar 
to how self is used for instance methods.

class X:
   x = 10

class Y(X):
   y = 5
   def foo(cls):
     print cls is Y
     print cls.x + cls.y
   foo = classmethod(foo)

HTH,
Shalabh




More information about the Python-list mailing list