property()
функция возвращает специальный descriptor object:
>>> property()
<property object at 0x10ff07940>
Именно этот объект, который имеет дополнительные методов:
>>> property().getter
<built-in method getter of property object at 0x10ff07998>
>>> property().setter
<built-in method setter of property object at 0x10ff07940>
>>> property().deleter
<built-in method deleter of property object at 0x10ff07998>
Они действуют как декораторы слишком. Они возвращают новый объект недвижимости:
>>> property().getter(None)
<property object at 0x10ff079f0>
Это копия старого объекта, но с заменой одной из функций.
Помните, что синтаксис @decorator
- это просто синтаксический сахар; Синтаксис:
@property
def foo(self): return self._foo
на самом деле означает то же самое, как
def foo(self): return self._foo
foo = property(foo)
так foo
функция заменяется property(foo)
, который мы видели выше, является особым объектом. Затем, когда вы используете @foo.setter()
, то, что вы делаете, вызывает то, что метод property().setter
, который я показал вам выше, который возвращает новую копию свойства, но на этот раз с заменой функции setter на декорированный метод.
Следующая последовательность также создает свойство полного включения, используя эти методы декоратора.
Сначала мы создаем некоторые функции и property
объекта только геттер:
>>> def getter(self): print 'Get!'
...
>>> def setter(self, value): print 'Set to {!r}!'.format(value)
...
>>> def deleter(self): print 'Delete!'
...
>>> prop = property(getter)
>>> prop.fget is getter
True
>>> prop.fset is None
True
>>> prop.fdel is None
True
Далее мы используем метод .setter()
добавить сеттер:
>>> prop = prop.setter(setter)
>>> prop.fget is getter
True
>>> prop.fset is setter
True
>>> prop.fdel is None
True
Последними мы добавим Deleter с .deleter()
>>> prop = prop.deleter(deleter)
>>> prop.fget is getter
True
>>> prop.fset is setter
True
>>> prop.fdel is deleter
True
Последнее, но не очередь, property
объект действует как descriptor object, поэтому она имеет .__get__()
, .__set__()
и .__delete__()
методы, чтобы крюк в случае атрибут получения, установки и удаления:
>>> class Foo(object): pass
...
>>> prop.__get__(Foo(), Foo)
Get!
>>> prop.__set__(Foo(), 'bar')
Set to 'bar'!
>>> prop.__delete__(Foo())
Delete!
Дескриптор Howto включает в себя pure python sample implementation из property()
типа:
class Property(object):
"Emulate PyProperty_Type() in Objects/descrobject.c"
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
if doc is None and fget is not None:
doc = fget.__doc__
self.__doc__ = doc
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError("unreadable attribute")
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError("can't set attribute")
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError("can't delete attribute")
self.fdel(obj)
def getter(self, fget):
return type(self)(fget, self.fset, self.fdel, self.__doc__)
def setter(self, fset):
return type(self)(self.fget, fset, self.fdel, self.__doc__)
def deleter(self, fdel):
return type(self)(self.fget, self.fset, fdel, self.__doc__)
См. Также: [Как работают свойства Python?] (Http://stackoverflow.com/q/6193556/562769) –
'property' - фактически класс (а не функция), хотя он, вероятно, вызывает вызов '__init __()' метод, когда вы делаете объект, конечно. Использование 'help (property)' из терминала проницательно. По какой-то причине 'help' также является классом. – Shule