如果我们person
在用行实例化对象后立即打开它person = Email("James")
,则将是这样的:
person {
"name" : "James",
"email" : "James@hotmail.com"
}
如果像您一样使用来更新name
该person
对象中的变量person.name = "Michael"
,然后person
再次打开该对象,则可能是:
person {
"name" : "Michael",
"email" : "James@hotmail.com"
}
请注意,在此阶段,它仍然是person
我们之前实例化的对象,并且该email
变量未从其先前状态更改,因为我们尚未对其进行任何处理。
通过将email
field设置为property
,并使用name
变量动态设置,@ chepner发布的答案非常好且干净。以下是@chepner的代码的副本:
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}'
property
是Python内置函数,property
对象具有以下方法:
现在,@chepner的答案中到底发生了什么?在下面的行中,我们将设置email
为property
:
@property
def email(self):
return f'{self.name}@hotmail.com'
并且此装饰功能也可以用作getter
例如person.email
。
请注意,在这里我们没有将其链接到变量(如Python文档示例所示),如果需要/需要,我们可以通过替换return
语句并在中设置_email
变量来实现__init__
:
def __init__(self, input_name):
self._name = input_name
self._email = f'{self._name}@hotmail.com'
@property
def email(self):
return self._email
然后,对于setter
和deleter
,我们可以将它们创建为:
@email.setter
def email(self, input_email):
self._email = input_email
@email.deleter
def email(self):
del self._email
请注意,getter
,setter
,和deleter
方法都具有相同的名称property
,只是不同的装饰。
从问题描述中,不需要支持单独更新电子邮件地址,但是仅在此示例之后,如果我们运行person.email = "Michael@hotmail.com"
,因为它是email
a property
,它将触发将setter
设置为_email
变量的值。
回到@chepner的答案中的details
方法:
def details(self):
return f'{self.name} | {self.email}'
通过执行此操作,self.email
我们触发,getter
以返回该return
语句中动态生成的电子邮件地址return f'{self.name}@hotmail.com'
。