Полная история немного сложна (см. Python: метод __getattribute__ и дескрипторы и python __getattribute__ override и @property decorator и перейдите по ссылкам на wiki по протоколам дескрипторов ), но вкратце вы пишете:
somevar.thing()
, когда хотите вызвать thing
, и вы пишете:
somevar.thing
, если вы хотите использовать значение thing
.Это использование аналогично функциям и функциям:
def f(arg):
print('f called, arg =', arg)
return 42
x = f('douglas adams')
print('f returned', x)
y = x
print('I just set y to x:', y)
y = f
print('this time I did not call', y)
, которые при запуске (как Python3 или с from __future__ import print_function
в Python2) выводят:
f called, arg = douglas adams
f returned 42
I just set y to x: 42
this time I did not call <function f at ...>
Если мыпопробуйте сделать y = x()
, это не удастся, потому что мы не можем вызвать 42
.
Если вы собираетесь определить, как использовать thing
, определите его как методесли он должен быть , называемым , и в качестве атрибута экземпляра, если он просто должен использоваться (и / или иметь какое-либо значение).Если вы примете неправильное решение - если вы сделаете его атрибутом экземпляра used / set, а потом выяснится, что вам нужна функция, - вы можете обойти его позже с помощью @property
.
Что особенногоо методах экземпляра заключается в том, что когда вы вызываете их - или даже когда нет - вы получаете дополнительный аргумент self
.Реализация, в которой это происходит, отличается в Python2 и Python3, но:
class K(object):
def method(self, arg):
print('method called, arg is', arg)
x = K()
x.method(42)
печатает:
method called, arg is 42
Обратите внимание, что если мы не вызываем егомы видим это как «связанный метод»:
print('x.method is', x.method)
производит:
x.method is <bound method K.method of <__main__.K object at ...>>
Если мы посмотрим на K.method
напрямую, разница между Python2 и Python3 обнаруживается:
$ python2 x.py
K.method is <unbound method K.method>
$ python3.6 x.py
K.method is <function K.method at ...>
но, в конце концов, это всего лишь дескрипторные протоколы, а реализация CPython способна сделать несколько кратких .