<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前言:
Python是物件導向的語言,一般情況下使用物件導向程式設計會使得開發效率更高,軟體質量更好,並且程式碼更易於擴充套件,可讀性和可維護性也更高。但是如果在一個較大的專案中,如果實體類非常多並且有非常複雜的屬性,你就會逐漸覺得Python的類寫起來是真·「累」。為什麼這樣說,看下下面這個Box
類,屬性有長(length
)、寬(width
)、高(hight
):
class Box: def __init__(self, length, width, hight): self.length = length self.width = width self.hight = hight
這樣倒沒有什麼問題,而且是符合Python
規範的寫法,初始化函數內每一個引數都需要用self.xxx = xxx
進行賦值,引數少了還好,但是如果引數過多了,只是引數賦值操作都夠寫一會的了,如果一個專案中類也有很多,那就真的要麻木了。
而且我們知道,在Python
中,想要自定義物件本身的列印輸出結果的時候,需要在它的類中實現__repr__()
方法,例如:
def __repr__(self): return '{}(length={}, width={}, hight={})'.format( self.__class__.__name__, self.length, self.width, self.hight)
實現了__repr__()
方法,當我們列印物件本身的時候,才會輸出我們自定義的字元。
box = Box(20, 15, 15) print(box) # 結果輸出為 Box(length=20, width=15, hight=15)
但是有時會因為麻煩,我們不願意去實現__repr__()
方法,但是不實現列印結果又不友好,就陷入了糾結之中。
如果我麼想要實現物件比較,有時候需要判斷2個物件是否相等或者比較大小,就要實現__eq__()
、 __lt__()
、__gt__()
等各種方法來實現物件之間的比較,例如:
def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented return (self.length, self.width, self.hight) == ( other.length, other.width, other.hight)
這樣我們又需要實現這幾個用於比較的方法。 比如說我們已經實現了上面說過的所有方法,然後又突然新增一個屬性結實度hardness,那麼整個類的方法都需要修改,這是非常折磨人的。 那麼有沒有一種方法,可以在建立類的時候自動新增上類似於上面提到的這些東西,答案是有的,那就是我們接下來要介紹的attrs
模組,它可以幫助我們很方便的定義類。
我們可以使用pip install attrs
進行安裝。
然後將上面的程式碼改造一下:
from attr import attrs, attrib @attrs class Box: length = attrib(type=int, default=0) width = attrib(type=int, default=0) hight = attrib(type=int, default=0) box1 = Box(20, 15, 15) print(box1) box2 = Box(30, 20, 20) print(box2 == box1) print(box2 > box1)
用模組內的attrs
修飾了Box類,再使用attrib
定義所有的屬性,同時指定了屬性的型別和預設值。而且我們沒有實現任何一個上面所提到的方法,但是確實實現了所有的功能。 現在如果我們新增一個屬性顏色color
,這個屬性不參與物件的比較,但是列印的時候要輸出,新增一個屬性結實度hardness
,這個屬性參與物件的比較,但是列印物件的時候不輸出,就非常簡單了:
from attr import attrs, attrib @attrs class Box: length = attrib(type=int, default=0) width = attrib(type=int, default=0) hight = attrib(type=int, default=0) color = attrib(repr=True, cmp=False, default=(0, 0, 0)) hardness = attrib(repr=False, cmp=True, default=0) box1 = Box(20, 15, 15, (255, 255, 255), 80) print("box1:", box1) box2 = Box(20, 15, 15, (255, 255, 0), 100) print("box2:", box2) print(box2 == box1) print(box2 > box1)
執行結果為:
也就是說,如果我們用了attrs庫的話,會讓類的定義變得高效簡潔,就不需要再寫哪些冗餘又複雜的程式碼了。 關於attrib()
,接收以下引數:
default
:屬性的預設值,如果沒有傳入初始化資料,那麼就會使用預設值validator
:驗證器,檢查傳入的引數是否合法repr
:是否參與物件列印時的輸出cmp
:是否參與物件比較hash
:是否進行去重init
:是否參與初始化,如果為False,那麼這個引數不能當做類的初始化引數,預設是Truemetadata
:後設資料,唯讀性的附加資料type
:型別,比如 int、str 等各種型別,預設為 Noneconverter
:轉換器,進行一些值的處理和轉換器,增加容錯性kw_only
:是否為強制關鍵字引數,預設為 False這裡我們只重點說一下驗證器和轉換器,其他的引數都很好理解。
有時候在設定一個屬性的時候必須要滿足某個條件,比如上面的顏色color
屬性,我們使用的是RGB三原色方式,例如黑色是(255,255,255),對於這種情況,我們就需要驗證屬性是否合法。
例如:
def color_is_valid(instance, attr, value): if not isinstance(value, set): raise ValueError(f"引數{attr.name}:{value}不合法!") for i in value: if not 0 <= i<= 255: raise ValueError(f"引數{attr.name}:{value}不合法!") @attrs class Box: length = attrib(type=int, default=0) width = attrib(type=int, default=0) hight = attrib(type=int, default=0) color = attrib(repr=True, cmp=False, validator=color_is_valid, default=(0, 0, 0)) hardness = attrib(repr=False, cmp=True, default=0) box1 = Box(20, 15, 15, (255, 255, 260), 80)
執行結果為:
上述程式碼中定義了一個驗證器color_is_valid()
方法來驗證顏色color
是否合法,不合法時就會拋異常。
驗證器方法接收三個引數:
instance
:類物件attr
:屬性名value
:屬性值而且attrs
模組也提供了許多內建驗證器,這裡就不做贅述了。
轉換器主要做一些值的處理和轉換,增加類的容錯性,比如一個屬性接收的是int型別,我們想要的是傳入了數位字串也不會報錯,那我們就可以增加轉換器,將字串自動轉為數位,例如:
def to_int(value): try: return int(value) except: return None @attrs class Box: length = attrib(type=int, default=0, converter=to_int) width = attrib(type=int, default=0, converter=to_int) hight = attrib(type=int, default=0) color = attrib(repr=True, cmp=False, default=(0, 0, 0)) hardness = attrib(repr=False, cmp=True, default=0) box1 = Box("20", "15", 15, (255, 255, 255), 80) print("box1:", box1) box2 = Box("2a", 15, 15, (255, 255, 0), 100) print("box2:", box2)
上面定義了一個方法to_int()
,可以將值轉化為數位型別,轉換異常就返回None
,這樣容錯性非常高了。
到此這篇關於Python attrs
提高物件導向程式設計效率詳細的文章就介紹到這了,更多相關Python attrs提高物件導向程式設計效率內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45