更新值后,该__init__
方法仍使用旧的属性值。
class Email:
def __init__(self, name):
self.name = name
self.email = self.name + "@hotmail.com"
def details(self):
return f'{self.name} | {self.email}'
person = Email("James")
print(person.details())
person.name = "Michael"
print(person.details())
Run Code Online (Sandbox Code Playgroud)
得到的输出:
James | James@hotmail.com
Michael | James@hotmail.com
Run Code Online (Sandbox Code Playgroud)
预期输出:
James | James@hotmail.com
Michael | Michael@hotmail.com
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
在此示例中,在类self.email
的__init__
方法中分配,仅在Email
创建的实例时调用。这样,何时self.name
重新分配,self.email
就不会更改。要解决此问题,可以使用property
装饰器:
class Email:
def __init__(self, name):
self._name = name
self._email = f'{name}@hotmail.com'
def details(self):
return f'{self._name} | {self._email}'
@property
def name(self):
return self._name
@name.setter
def name(self, _new_name):
self._name = _new_name
self._email = f'{_new_name}@hotmail.com'
person = Email("James")
print(person.details())
person.name = "Michael"
print(person.details())
Run Code Online (Sandbox Code Playgroud)
输出:
James | James@hotmail.com
Michael | Michael@hotmail.com
Run Code Online (Sandbox Code Playgroud)
最简单的解决方法是制作email
一个属性,而不是您在中设置的属性__init__
。
class Email:
def __init__(self, name):
self.name = name
# self.email = self.name + "@hotmail.com"
@property
def email(self):
return f'{self.name}@hotmail.com'
def details(self):
return f'{self.name} | {self.email}'
Run Code Online (Sandbox Code Playgroud)