W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
你在類中需要重復的定義一些執(zhí)行相同邏輯的屬性方法,比如進行類型檢查,怎樣去簡化這些重復代碼呢?
考慮下一個簡單的類,它的屬性由屬性方法包裝:
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
可以看到,為了實現(xiàn)屬性值的類型檢查我們寫了很多的重復代碼。 只要你以后看到類似這樣的代碼,你都應該想辦法去簡化它。 一個可行的方法是創(chuàng)建一個函數(shù)用來定義屬性并返回它。例如:
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ù)或者閉包的一個重要特性,它們很像一個宏。例子中的函數(shù)<span class="pre" style="box-sizing: border-box;">typed_property()</span>
?看上去有點難理解,其實它所做的僅僅就是為你生成屬性并返回這個屬性對象。 因此,當在一個類中使用它的時候,效果跟將它里面的代碼放到類定義中去是一樣的。 盡管屬性的<span class="pre" style="box-sizing: border-box;">getter</span>
?和?<span class="pre" style="box-sizing: border-box;">setter</span>
?方法訪問了本地變量如?<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>
?,這個很正常,這些變量的值會保存在閉包當中。
我們還可以使用?<span class="pre" style="box-sizing: border-box;">functools.partial()</span>
?來稍稍改變下這個例子,很有趣。例如,你可以像下面這樣:
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
其實你可以發(fā)現(xiàn),這里的代碼跟8.13小節(jié)中的類型系統(tǒng)描述器代碼有些相似。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: