Python 重写使用@property设置的属性
我想知道在这种情况下如何更新使用@property decorator设置的属性。(下面的代码将告诉您的不仅仅是文字……) 当我尝试在没有设置器的情况下更新电子邮件时,我得到了一个AttributeError:can't set属性。当我使用setter时,没有任何变化。新邮件既不使用名字也不使用姓氏 有人能帮忙吗Python 重写使用@property设置的属性,python,Python,我想知道在这种情况下如何更新使用@property decorator设置的属性。(下面的代码将告诉您的不仅仅是文字……) 当我尝试在没有设置器的情况下更新电子邮件时,我得到了一个AttributeError:can't set属性。当我使用setter时,没有任何变化。新邮件既不使用名字也不使用姓氏 有人能帮忙吗 class Employee: def __init__(self, first, last): self.first = first sel
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
正如我在我的评论中所发布的,您需要首先确定新电子邮件是否在
中。last@email.com
然后只需设置first
和last
属性
虽然我不会使用电子邮件作为属性,如果你是基于名称创建的,你应该更改名称本身
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>
我认为这里最简单的方法是去掉属性,而将
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'
如果您确实想要保留该属性,则setter需要更新实例属性:
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
但是,除此之外,第一个选项更简单。您应该使用第一个和最后一个属性来更改电子邮件,否则您需要确保设置为第一个时的电子邮件。last@email.com格式化然后设置这些属性,然后诚实地说,您应该只返回None或根本没有return语句,因为这意味着None return。尽管说实话,你最终还是要决定你想在这里使用什么逻辑,要么你决定先发邮件,要么最后发邮件,要么它们是分开的;显式设置电子邮件地址实际上没有意义。如果没有明确的地址设置,
email.com
地址应该是默认地址吗?非常感谢,克里斯。我唯一不清楚的是单下划线的用法:我只能注意到,如果我删除它,我会得到一个递归错误,尽管我一直认为单下划线纯粹是常规的,不会影响代码的行为(除非使用*导入)。显然情况并非如此……正如你所说,下划线是惯例。如果删除它,则会创建一种情况,其中有两个名称相同的东西:email属性和email属性。这种重复会产生歧义-当您引用employee.email
时,您是引用实例变量还是属性?因此,它们需要单独的名称。希望能有帮助。我是编程新手,但可能也有点笨…:当我使用“\u email”时,复制属性/属性仍然保留。我很困惑。看看这条老线索,很好地解释了属性以及它们如何在引擎盖下工作:
@email.setter
def email(self, addr):
if '@' not in addr:
raise ValueError('nope!')
self._email = addr