如何解决在 setter 和 @property 装饰器中遇到一些麻烦和困惑,并非所有在 `__init__` 中定义的属性都被更新
class Employee:
def __init__(self,first,last,pay):
self.first = first
self.last = last
self.pay = pay
self.annual_pay = 12*pay
self.email = self.first + '.' + self.last + '@email.com'
@property
def fullname(self):
return ('{} {}'.format(self.first,self.last))
@fullname.setter
def fullname(self,name):
first,last = name.split(' ')
self.first = first
self.last = last
emp1 = Employee('test1','subject1',10000)
emp1.fullname='test2 subject2'
print(emp1.fullname)
print(emp1.email)
我使用 setter 为用户分配一个 fullname() 并覆盖顶部已经由 init 设置的属性,但在输出中它只将 fullname 更改为 test2 subject2 同时电子邮件未更改为 test1 .subject1@email.com(我从教程中学到,我认为我们可以通过这个 setter 功能覆盖默认属性)(而且那个家伙没有像我那样在 init 中使用电子邮件,而是他有一个单独的函数,带有@property 装饰器)
解决方法
那是因为当您运行 __init__()
时,电子邮件的值被计算并保存。仅仅因为您更改 self.first
和 self.last
并不意味着 self.email
会受到影响,因为它没有保存与这些变量的关系。保存为字符串。
示例:
a = "hello"
b = "world"
c = a + b
a = "goodbye"
print(c)
>>> "hello world"
此处,c
设置为 a+b
,并且在执行该行时保存该值。在我们已经赋予 a
其值之后更改 c
不会改变它。它已经设置,我们必须再次执行 c = a+b
才能打印出 goodbye world
。
在你的情况下,你必须在 setter 中修改它:
@fullname.setter
def fullname(self,name):
first,last = name.split(' ')
self.first = first
self.last = last
self.email = self.first + '.' + self.last + '@email.com'
然而,这不是一个好习惯,因为 setter 应该只更改您正在访问的特定变量。这就是为什么您正在阅读的教程有一个电子邮件函数的原因:如果您希望根据 first
和 last
的任何值动态计算它当你检查它的时候,你应该总是使用一个函数:
def email(self):
return self.first + '.' + self.last + '@email.com'
print(emp1.email())
如果需要,您可以像教程一样使用 property
装饰器:
@property
def email(self):
return self.first + '.' + self.last + '@email.com'
这只是语法糖,让您可以像以前一样调用它:
print(emp1.email)
不必像函数一样调用它,尽管仅此而已。
作为旁注,我建议使用 string formatting,在这种情况下,通常首选使用 +
将字符串连接在一起:
return f"{self.first}.{self.last}@email.com"
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。