Am 17.11.2011 03:30 schrieb Roy Smith:
When I run this (python 2.6.1):
class C:
@staticmethod
def foo():
pass
print "inside", foo, callable(foo)
print "outside", C.foo, callable(C.foo)
I get:
inside<staticmethod object at 0x421df0> False
outside<function foo at 0x41e6f0> True
Right. The reason is that on an attribute access, you get a __get__ call
of the "real" attribute.
That is, if your class has a "regular" method, it is stored there as a
formal function. But if you access it (C.f), you get
C.__dict__["f"].__get__(None, C) (not sure about the arguments, but you
should get the idea).
A functions __get__ returns a unbound or bound method, depending on its
own arguments.
With a static method, you don't want this to happen. So you wrap your
"regular" function into a staticmethod object, which has a __get__()
method itself just returning the wrapped function object.
Look at this:
>>> class C(object): pass
...
>>> f=lambda *a:a
>>> C.f=f
>>> s=staticmethod(f)
>>> C.s=s
>>> # Now we test the access
...
>>> f
<function <lambda> at 0x00B43E30>
>>> s
<staticmethod object at 0x00B48A90>
>>> C.f
<unbound method C.<lambda>>
>>> C().f
<bound method C.<lambda> of <__main__.C object at 0x00B48810>>
>>> C.s
<function <lambda> at 0x00B43E30>
>>> C().s
<function <lambda> at 0x00B43E30>
>>> f.__get__(None, C)
<unbound method C.<lambda>>
>>> f.__get__(C(), C)
<bound method C.<lambda> of <__main__.C object at 0x00B48AD0>>
>>> s.__get__(None, C)
<function <lambda> at 0x00B43E30>
>>> s.__get__(C(), C)
<function <lambda> at 0x00B43E30>
That's how things work.
If you want to get back the "real" function from a staticmethod, you
either call its __get__ with an arbitrary argument, or you do it the
clean way and do a
def deref(s):
class C(object): s=s
return s.s
and so do a
class User(Document):
@staticmethod
def _get_next_id():
[blah, blah, blah]
return id
user_id = IntField(required=True, default=deref(_get_next_id))
HTH,
Thomas
--
http://mail.python.org/mailman/listinfo/python-list