Когда object.__setattr__()
находит дескриптор привязки (дескриптор с методом __set__
), он вызывает его вместо установки пары имя: значение в __dict__
экземпляра - что, очевидно, является ожидаемым на самом деле xD.
Так что в вашем случае, когда вы создаете экземпляр Person
:
Person("ankit", 29)
Python вызывает инициализатор:
def __init__(self, name, age):
self.name = name
self.age = age
, который вызывает Person.age.__set__(self, age)
, который вызывает fset(self, value)
:
def fset(self, value):
print("Setting ")
self.age = value
, который вызывает Person.age.__set__(self, age)
, который вызывает fset(self, value)
:
def fset(self, value):
print("Setting ")
self.age = value
, который вызывает Person.age.__set__(self, age)
, который вызывает fset(self, value)
:
def fset(self, value):
print("Setting ")
self.age = value
, который вызывает Person.age.__set__(self, age)
, который вызывает fset(self, value)
:
def fset(self, value):
print("Setting ")
self.age = value
, который вызывает Person.age.__set__(self, age)
, который вызывает fset(self, value)
:
def fset(self, value):
print("Setting ")
self.age = value
и т. Д. И т. Д. И т. Д. И т. Д....
IOW вы не можете использовать одно и то же имя для property
и базового атрибута экземпляра, поскольку property
полностью скрывает атрибут экземпляра.
Канонически, каждый используетАтрибут реализации с тем же именем, что и property
, только с префиксом единственного начального подчеркивания (соглашение Python для «защищенного атрибута»):
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def fget(self):
print("Getting ")
return self._age
def fset(self, value):
print("Setting ")
self._age = value
def fdel(self):
print("Deleting")
del self._age
age = property(fget, fset, fdel, "I'm the property.")