覆盖使用 @property 设置的属性



我想知道如何更新在这种情况下使用 @property 装饰器设置的属性。(下面的代码会告诉你的不仅仅是文字...

当我尝试在没有设置器的情况下更新电子邮件时,我收到一个属性错误:无法设置属性。当我使用二传手时,没有任何变化。新电子邮件既不使用名字也不使用姓氏。

有人可以帮忙吗?

class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
@property
def email(self):
return f"{self.first}.{self.last}@email.com".lower()
# @email.setter
# def email(self, new_email):
#     return new_email

我认为这里最直接的途径是取消该属性,而是email默认为first.last的可选参数:

class Employee:
def __init__(self, first, last, email=None):
self.first = first
self.last = last
self.email = email if email else f"{first}.{last}@email.com".lower()

现在,您可以使用常用的点表示法修改现有实例的电子邮件地址:

>>> e = Employee('John', 'Doe')
>>> e.email
'john.doe@email.com'
>>>
>>> e.email = 'a@b.com'
>>> e.email
'a@b.com'

如果您确实打算保留该属性,则资源库需要更新实例属性:

class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
self._email = f"{first}.{last}@email.com".lower()
@property
def email(self):
return self._email
@email.setter
def email(self, addr):
self._email = addr

如果您需要在途中进行一些验证,则可以选择此模式 - 例如,确认新电子邮件具有@符号:

@email.setter
def email(self, addr):
if '@' not in addr:
raise ValueError('nope!')
self._email = addr

但除此之外,第一种选择会更简单一些。

正如我在评论中发布的那样,您需要确定新电子邮件是否在first.last@email.com然后只需设置firstlast属性即可。

虽然我不会将电子邮件用作属性,但如果您根据名称创建电子邮件,您应该更改名称本身。

class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
def email(self):
return f"{self.first}.{self.last}@email.com".lower()
def __repr__(self):
return f"<Employee | {self.first} {self.last}>"
john = Employee('John', 'Smith')
print(john)
#<Employee | John Smith>
john.first = "Joe"
print(john)
#<Employee | Joe Smith>

否则,如果您想要电子邮件的设置器,那么我建议使用它来设置第一个和最后一个属性,但您不需要返回值,因为您只是设置您已经知道的电子邮件。我会使用re库来检查电子邮件的格式是否正确。这是一个非常粗略的例子:

@email.setter
def email(self, new_email):
try:
self.first, self.last = re.search('(?P<first>w+).(?P<last>w+)@S+', email).group('first', 'last'))
except AttributeError:
raise ValueError("Email must be in "first.last@email.com")

最新更新