python - What magic does staticmethod() do, so that the static method is always called without the instance parameter? -
i trying understand how static methods work internally. know how use @staticmethod
decorator avoiding use in post in order dive deeper how static methods work , ask questions.
from know python, if there class a
, calling a.foo()
calls foo()
no arguments whereas calling a().foo()
calls foo()
1 argument 1 argument instance a()
itself.
however, in case of static methods, seems foo()
called no arguments whether call a.foo()
or a().foo()
.
proof below:
>>> class a: ... x = 'hi' ... def foo(): ... print('hello, world') ... bar = staticmethod(foo) ... >>> a.bar() hello, world >>> a().bar() hello, world >>> a.bar <function a.foo @ 0x00000000005927b8> >>> a().bar <function a.foo @ 0x00000000005927b8> >>> a.bar(1) traceback (most recent call last): file "<stdin>", line 1, in <module> typeerror: foo() takes 0 positional arguments 1 given >>> a().bar(1) traceback (most recent call last): file "<stdin>", line 1, in <module> typeerror: foo() takes 0 positional arguments 1 given
so right in concluding staticmethod()
function magic such foo()
called 0 arguments?
if define own staticmethod()
in own python code, how it? possible define such method our own python code, or can such function defined builtin?
it's implemented descriptor. example:
in [1]: class mystaticmethod(object): ...: def __init__(self, func): ...: self._func = func ...: def __get__(self, inst, cls): ...: return self._func ...: in [2]: class a(object): ...: @mystaticmethod ...: def foo(): ...: print('hello, world!') ...: in [3]: a.foo() hello, world! in [4]: a().foo() hello, world!
in same way can define classmethod
, passing cls
original function:
in [5]: functools import partial ...: ...: class myclassmethod(object): ...: def __init__(self, func): ...: self._func = func ...: def __get__(self, inst, cls): ...: return partial(self._func, cls) in [6]: class a(object): ...: @myclassmethod ...: def foo(cls): ...: print('in class: {}'.format(cls)) ...: in [7]: a.foo() in class: <class '__main__.a'> in [8]: a().foo() in class: <class '__main__.a'>
Comments
Post a Comment