staticmethod problems

N

Neil Zanella

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.

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.

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)?
#Y.foo2() # doesn't work either. Why?

Y.foo3() # works

print Y.x # Since the object.attribute notation is used
# polymorphism is used to locate attribute x.
# Since class object Y does not contain x the
# immediate parent X is searched and x found
# therein. Finally the value of x is printed.

class XA:
x = 10

class YA(XA):
def foo(self):
print self.x

YA().foo() # Since the object.attribute notation is used
# polymorphism is used to locate attribute foo()
# which is not found in instance object YA() so
# class object YA is searched next and foo() is
# found therein and run.
#
# Once run the object.attribute notation is used
# to locate x which is not found in instance object
# self (AKA YA()) so class object YA is searched and
# since x is not found there either the immediate parent
# class object XA in the inheritance hierarchy is searched
# and attribute x is found therein.
#
# Once the x is found the object it references is printed.
 
S

Shalabh Chaturvedi

Neil said:
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 said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,965
Messages
2,570,148
Members
46,710
Latest member
FredricRen

Latest Threads

Top