W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
你在類(lèi)中需要重復(fù)的定義一些執(zhí)行相同邏輯的屬性方法,比如進(jìn)行類(lèi)型檢查,怎樣去簡(jiǎn)化這些重復(fù)代碼呢?
考慮下一個(gè)簡(jiǎn)單的類(lèi),它的屬性由屬性方法包裝:
class Person:
def __init__(self, name ,age):
self.name = name
self.age = age
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not isinstance(value, str):
raise TypeError('name must be a string')
self._name = value
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise TypeError('age must be an int')
self._age = value
可以看到,為了實(shí)現(xiàn)屬性值的類(lèi)型檢查我們寫(xiě)了很多的重復(fù)代碼。 只要你以后看到類(lèi)似這樣的代碼,你都應(yīng)該想辦法去簡(jiǎn)化它。 一個(gè)可行的方法是創(chuàng)建一個(gè)函數(shù)用來(lái)定義屬性并返回它。例如:
def typed_property(name, expected_type):
storage_name = '_' + name
@property
def prop(self):
return getattr(self, storage_name)
@prop.setter
def prop(self, value):
if not isinstance(value, expected_type):
raise TypeError('{} must be a {}'.format(name, expected_type))
setattr(self, storage_name, value)
return prop
# Example use
class Person:
name = typed_property('name', str)
age = typed_property('age', int)
def __init__(self, name, age):
self.name = name
self.age = age
本節(jié)我們演示內(nèi)部函數(shù)或者閉包的一個(gè)重要特性,它們很像一個(gè)宏。例子中的函數(shù)<span class="pre" style="box-sizing: border-box;">typed_property()</span>
?看上去有點(diǎn)難理解,其實(shí)它所做的僅僅就是為你生成屬性并返回這個(gè)屬性對(duì)象。 因此,當(dāng)在一個(gè)類(lèi)中使用它的時(shí)候,效果跟將它里面的代碼放到類(lèi)定義中去是一樣的。 盡管屬性的<span class="pre" style="box-sizing: border-box;">getter</span>
?和?<span class="pre" style="box-sizing: border-box;">setter</span>
?方法訪問(wèn)了本地變量如?<span class="pre" style="box-sizing: border-box;">name</span>
?,?<span class="pre" style="box-sizing: border-box;">expected_type</span>
?以及?<span class="pre" style="box-sizing: border-box;">storate_name</span>
?,這個(gè)很正常,這些變量的值會(huì)保存在閉包當(dāng)中。
我們還可以使用?<span class="pre" style="box-sizing: border-box;">functools.partial()</span>
?來(lái)稍稍改變下這個(gè)例子,很有趣。例如,你可以像下面這樣:
from functools import partial
String = partial(typed_property, expected_type=str)
Integer = partial(typed_property, expected_type=int)
# Example:
class Person:
name = String('name')
age = Integer('age')
def __init__(self, name, age):
self.name = name
self.age = age
其實(shí)你可以發(fā)現(xiàn),這里的代碼跟8.13小節(jié)中的類(lèi)型系統(tǒng)描述器代碼有些相似。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: