Вызов статического метода внутри инициализации контейнеров уровня класса - PullRequest
14 голосов
/ 14 октября 2010

Учитывая следующий пример класса:

class Foo:

    def aStaticMethod():
        return "aStaticMethod"

    aVariable = staticmethod(aStaticMethod)
    aTuple = (staticmethod(aStaticMethod),)
    aList = [staticmethod(aStaticMethod)]

print Foo.aVariable()
print Foo.aTuple[0]()
print Foo.aList[0]()

Почему вызов aVariable работает правильно, но с aTuple и aList он возвращает ошибку 'staticmethod' object is not callable?

1 Ответ

16 голосов
/ 14 октября 2010

Это потому, что статический метод является дескриптором.Когда вы присоединяете его к классу и вызываете его с обычным синтаксисом, python вызывает его метод __get__, который возвращает вызываемый объект.Когда вы работаете с ним как с чистым дескриптором, python никогда не вызывает его метод __get__, и вы в конечном итоге пытаетесь вызвать дескриптор напрямую, который не вызывается.заполните данные для себя:

>>> Foo.aTuple[0].__get__(None, Foo)()
'aStaticMethod'

Здесь None передается параметру instance (экземпляр, к которому осуществляется доступ к дескриптору), а Foo - owner параметр (класс, в котором находится этот экземпляр дескриптора).Это заставляет его возвращать фактическую вызываемую функцию:

>>> Foo.aTuple[0].__get__(None, Foo)
<function aStaticMethod at 0xb776daac>
...