Вы можете видеть, что staticmethod
может принимать любой аргумент:
>>> x = staticmethod(3)
и что он действительно не может быть вызван:
>>> x()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'staticmethod' object is not callable
staticmethod
не подходит гораздо больше, чем хранить ссылку на свой аргумент. «Magi c» возникает, когда вы пытаетесь получить доступ к объекту staticmethod
как атрибуту объекта class
или экземпляру класса. Когда вы это сделаете, вы получите результат метода staticmethod
метода __get__
, который ... то, что вы изначально обернули.
>>> x.__get__(x)
3
Не беспокойтесь о том, почему мы передали x
в качестве аргумента; достаточно сказать, что staticmethod.__get__
в основном игнорирует его аргументы.
Когда вы заключаете функцию в оператор class
, staticmethod
сохраняет ссылку на функцию, которая будет вызвана позже, когда вы просите об этом.
>>> class Foo(object):
... @staticmethod
... def x():
... pass
...
>>> type(Foo.__dict__['x'])
<type 'staticmethod'>
>>> type(Foo.x)
<type 'function'>
Методы экземпляра работают так же, как и они, потому что function.__get__
возвращает экземпляр method
, который в некотором смысле только в первоначальной функции частично применил экземпляр, который вызывает это. Возможно, вы видели, что x.foo()
совпадает с type(x).foo(x)
. причина , которая является истинной, заключается в том, что x.foo
сначала разрешается в type(x).foo
, что само по себе оценивается в type(x).__dict__['foo'].__get__(x, type(x)
. Возвращаемое значение function.__get__
в основном является оболочкой для функции foo
, но с x
, уже предоставленным в качестве первого аргумента.
staticmethod
Основная цель - предоставить другой __get__
method.
Кстати, classmethod
служит той же цели. classmethod.__get__
возвращает то, что вызывает упакованную функцию с class в качестве первого аргумента, независимо от того, вызываете ли вы метод класса из экземпляра класса или самого класса.