John Smith曾经是我的好基友,没有之一,今天我们拿他做个试验:
初始代码,我们做一个打印员工John Smith信息的类,实例emp_1会用类属性输出:
class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
self.email = first + "." + last + '@email.com'
def fullname(self):
return '{} {}'.format(self.first, self.last)
emp_1 = Employee('John', 'Smith')
print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname())
John
John.Smith@email.com
John Smith
下面,当我们在类外修改了实例emp_1的属性,那么实例属性输出也改变;不过,你会发现问题,员工的first name和last name被改变了,但是,email却没有自动跟着改变。
class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
self.email = first + "." + last + '@email.com'
def fullname(self):
return '{} {}'.format(self.first, self.last)
emp_1 = Employee('John', 'Smith')
#New edit
emp_1.first = 'Jim'
print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname())
Jim
John.Smith@email.com
Jim Smith
Anyway,我还是想让email自动改变,在Python中该怎么办呢?
我们可以定义一个函数输出;不过你会发现,你需要一个讨厌的括号才能像刚才一样去调出email。
class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
# self.email = first + "." + last + '@email.com'
def email(self):
return '{}.{}@email.com'.format(self.first, self.last)
def fullname(self):
return '{} {}'.format(self.first, self.last)
emp_1 = Employee('John', 'Smith')
#New edit
emp_1.first = 'Jim'
print(emp_1.first)
print(emp_1.email())
print(emp_1.fullname())
Jim
Jim.Smith@email.com
Jim Smith
当我们还是想像调用属性一样来调用函数return结果,这时候,一个叫做property的装饰器说它可以解决完美主意者的烦恼;当然,当fullname发现这个技巧时候,它也果断跟进了一个@property,并脱掉了它的括号,因为这样很性感,特别是在一个完美的夏天。
class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
# self.email = first + "." + last + '@email.com'
@property
def email(self):
return '{}.{}@email.com'.format(self.first, self.last)
@property
def fullname(self):
return '{} {}'.format(self.first, self.last)
emp_1 = Employee('John', 'Smith')
#New edit
emp_1.first = 'Jim'
print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)
Jim
Jim.Smith@email.com
Jim Smith
于是,John很兴奋,因为其实他想改名很久了,他直接来了个:
emp_1.email = ‘Lady.Gaga@email.com’
emp_1.fullname = ‘Lady GaGa’
可是,结果脱掉外套后的他,摔了一个大跟头:AttributeError: can’t set attribute
class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
# self.email = first + "." + last + '@email.com'
@property
def email(self):
return '{}.{}@email.com'.format(self.first, self.last)
@property
def fullname(self):
return '{} {}'.format(self.first, self.last)
emp_1 = Employee('John', 'Smith')
emp_1.email = 'Lady.Gaga@email.com'
emp_1.fullname = 'Lady GaGa'
print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-43-05f72f854431> in <module>()
13 emp_1 = Employee('John', 'Smith')
14
---> 15 emp_1.email = 'Lady.Gaga@email.com'
16 emp_1.fullname = 'Lady GaGa'
17
AttributeError: can't set attribute
这时候,property说话了,它说:除了帮你脱掉外套,我还可以做更多…
class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
@property
def email(self):
return '{}.{}@email.com'.format(self.first, self.last)
@property
def fullname(self):
return '{} {}'.format(self.first, self.last)
@fullname.setter
def fullname(self, name):
first, last = name.split(' ')
# fullname的定义方式为emp_1.fullname = 'Lady Gaga',所以split一下
self.first = first
self.last = last
emp_1 = Employee('John', 'Smith')
emp_1.fullname = 'Lady Gaga'
print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)
Lady
Lady.Gaga@email.com
Lady Gaga
Jonh问:你为什么不早说?竟然有这种神操作,我不想活了。property说:如此需求,我也可以帮你实现:
class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
@property
def email(self):
return '{}.{}@email.com'.format(self.first, self.last)
@property
def fullname(self):
return '{} {}'.format(self.first, self.last)
@fullname.setter
def fullname(self, name):
first, last = name.split(' ')
# fullname的定义方式为emp_1.fullname = 'Lady Gaga',所以split一下
self.first = first
self.last = last
@fullname.deleter
def fullname(self):
print("Gandiao Name")
self.first = None
self.last = None
emp_1 = Employee('John', 'Smith')
emp_1.fullname = 'Lady Gaga'
print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)
print("before deleter")
del emp_1.fullname
print("after deleter")
print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)
Lady
Lady.Gaga@email.com
Lady Gaga
before deleter
Gandiao Name
after deleter
None
None.None@email.com
None None
Jonh惊呆了,说:你,你竟然删除了我…