Один из способов прояснить это - продемонстрировать это на конкретном примере, который ведет себя так: дескриптор встроенный property
:
class C(object):
@property
def x(self):
"This is a property object, not a function"
return self._x
@x.setter
def x(self, val):
self._x = val
>>> c = C()
>>> c.x = 1
>>> c.x
1
>>> C.x
<property object at 0x2396100>
>>> C.x.__doc__
'This is a property object, not a function'
>>> C.x.getter.__doc__
'Descriptor to change the getter on a property.'
>>> C.x.setter.__doc__
'Descriptor to change the setter on a property.'
>>> C.x.deleter.__doc__
'Descriptor to change the deleter on a property.'
Первый вызов property
(в качестве декоратора) означает, что x
является , а не функцией - это дескриптор свойства. Особенностью свойств является то, что они позволяют вам изначально определить только метод fget
, а затем предоставить fset
и fdel
позже, используя декораторы property.setter
и property.deleter
(хотя каждый из них создает новый объект свойства, вам нужно обязательно использовать одно и то же имя каждый раз).
Нечто подобное обычно имеет место, когда вы видите код, использующий этот тип шаблона. В идеале, присвоение имен декораторам позволит достаточно ясно понять, что происходит (например, большинство людей, кажется, понимают идиому для определения property
атрибутов достаточно легко).