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
[email protected]
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
[email protected]
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
[email protected]
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
[email protected]
Jim Smith
於是,John很興奮,因爲其實他想改名很久了,他直接來了個:
emp_1.email = ‘[email protected]’
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 = '[email protected]'
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 = '[email protected]'
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
[email protected]
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
[email protected]
Lady Gaga
before deleter
Gandiao Name
after deleter
None
[email protected]
None None
Jonh驚呆了,說:你,你竟然刪除了我…