国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python 面向?qū)ο缶幊蘋OP (四) 寫類神器:attrs

netmou / 3552人閱讀

摘要:它的目標(biāo)就是在不減慢你編程速度的前提下,幫助你來編寫簡潔而又正確的代碼。對于這種情況,我們就需要有條件來控制某些屬性不能為非法值。所以,一定要在里面某個錯誤。

使用attrs解放雙手

大家好,這一期我想和大家分享一個OOP編程的高效神器:attrs庫

首先我們來介紹下 attrs 這個庫,其官方的介紹如下:

attrs 是這樣的一個 Python 工具包,它能將你從繁綜復(fù)雜的實現(xiàn)上解脫出來,享受編寫 Python 類的快樂。它的目標(biāo)就是在不減慢你編程速度的前提下,幫助你來編寫簡潔而又正確的代碼。

因此用了它,定義和實現(xiàn) Python 類變得更加簡潔和高效

首先明確一點,我們現(xiàn)在是裝了 attrs 和 cattrs 這兩個庫,但是實際導(dǎo)入的時候是使用 attr 和 cattr 這兩個包,是不帶 s 的。

在 attr 這個庫里面有兩個比較常用的組件叫做 attrs 和 attr,前者是主要用來修飾一個自定義類的,后者是定義類里面的一個字段的。下面是一個小例子

from attr import attrs,attrib

@attrs
class Person:
    name = attrib(type = str,default="")
    age = attrib(type = int,default=0)
    sex = attrib(type = str,default="")

if __name__ == "__main__":
    first_person = Person("John",18,"M")
    print(first_person)

Out:Person(name="John", age=18, sex="M")

主要作用

可以發(fā)現(xiàn),Person這個類 三個屬性都只寫了一次,同時還指定了各個字段的類型和默認(rèn)值,另外也不需要再定義 init 方法和 repr 方法了,非常簡潔

實際上,主要是 attrs 這個修飾符起了作用,然后根據(jù)定義的 attrib 屬性自動幫我們實現(xiàn)了 initrepreqneltlegtgehash 這幾個方法

深入了解

現(xiàn)在來用實例看一下:

first_person = Person("John",18,"M")
second_person = Person("Nancy",16,"F")

print("Equal:", first_person == second_person)  #False
print("Not Equal(ne):", first_person != second_person) #True
print("Less Than(lt):", first_person.age < second_person.age) #False
print("Less or Equal(le):", first_person.age <= second_person.age) #False
print("Greater Than(gt):", first_person.age > second_person.age) #True
print("Greater or Equal(ge):", first_person.age >= second_person.age) #True
屬性定義

對于 attrib 的定義,可以傳入各種參數(shù),不同的參數(shù)對于這個類的定義有非常大的影響。

下面來詳細(xì)了解一下每個屬性的具體參數(shù)和用法。

首先我們用 attrs 里面的 fields 方法可以查看一下

from attr import attrs, attrib,fields
print(fields(Person))

(Attribute(name="name", default="", validator=None, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=, converter=None, kw_only=False), Attribute(name="age", default=0, validator=None, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=, converter=None, kw_only=False), Attribute(name="sex", default="", validator=None, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=, converter=None, kw_only=False))
參數(shù) 解釋
name 屬性的名字,是一個字符串類型
default 屬性的默認(rèn)值,如果沒有傳入初始化數(shù)據(jù),那么就會使用默認(rèn)值,如果沒有默認(rèn)值定義,那么就是 NOTHING,即沒有默認(rèn)值
validator 驗證器,檢查傳入的參數(shù)是否合法
init 是否參與初始化,如果為 False,那么這個參數(shù)不能當(dāng)做類的初始化參數(shù),默認(rèn)是 True。
type 類型,比如 int、str 等各種類型,默認(rèn)為 None
metadata 元數(shù)據(jù),只讀性的附加數(shù)據(jù)
converter 轉(zhuǎn)換器,進(jìn)行一些值的處理和轉(zhuǎn)換器,增加容錯性
kw_only 是否為強制關(guān)鍵字參數(shù),默認(rèn)為 False
初始化

如果一個類的某些屬性不想?yún)⑴c初始化,比如想直接設(shè)置一個初始值,一直固定不變,我們可以將屬性的 init 參數(shù)設(shè)置為 False,看一個實例:

from attr import attrs,attrib

@attrs
class Person:
    name = attrib(type = str)
    age = attrib(init=False)
    sex = attrib(type = str)

first = Person("John","M") # Person(name="John", age=NOTHING, sex="M")

second = Person("Mike",89,"M")
#TypeError: __init__() takes 3 positional arguments but 4 were given

可以發(fā)現(xiàn),first沒有問題,但是second會報錯,因為age沒有參與初始化,只剩了self,age,sex

強制關(guān)鍵字

強制關(guān)鍵字是 Python 里面的一個特性,在傳入的時候必須使用關(guān)鍵字的名字來傳入

設(shè)置了強制關(guān)鍵字參數(shù)的屬性必須要放在后面,其后面不能再有非強制關(guān)鍵字參數(shù)的屬性

我們還是拿一樣的例子,這回把sex的參數(shù)

from attr import attrs,attrib

@attrs
class Person:
    name = attrib(type = str)
    age = attrib(type = str)
    sex = attrib(kw_only=True)
    
first = Person("John",18,sex="M")
#Person(name="John", age=18, sex="M")

如果初始化first時使用Person("John",18,"M")則會報錯

驗證器

有時候在設(shè)置一個屬性的時候必須要滿足某個條件,比如性別必須要是男或者女,否則就不合法。對于這種情況,我們就需要有條件來控制某些屬性不能為非法值。

from attr import attrs, attrib

def is_valid_gender(instance, attribute, value):
    if value not in ("M", "F"):
        raise ValueError(f"gender {value} is not valid")
        
@attrs
class Person:
    name = attrib(type = str)
    age = attrib(type = str)
    sex = attrib(validator=is_valid_gender)

在這里我們定義了一個驗證器 Validator 方法,叫做 is_valid_gender,其中 gender 定義的時候傳入了一個參數(shù) validator,其值就是我們定義的 Validator 方法:

instance:類對象

attribute:屬性名

value:屬性值

下面做了兩個實驗,一個就是正常傳入 "M",另一個寫錯了,寫的是 "X":

first = Person("John",18,"M")  
# Person(name="John", age=18, sex="M")

second = Person("Ann",29,"X")  
ValueError: gender X is not valid

second報錯了,因為其值不是正常的性別,所以程序直接報錯終止
注意在 Validator 里面返回 True 或 False 是沒用的,錯誤的值還會被照常復(fù)制。所以,一定要在 Validator 里面 raise 某個錯誤。

另外 attrs 庫里面還給我們內(nèi)置了好多 Validator,比如判斷類型,這里如果規(guī)定age必須為 int 類型:

age  =attrib(validator=validators.instance_of(int))

另外 validator 參數(shù)還支持多個 Validator,比如我們要設(shè)置既要是數(shù)字,又要小于 100,那么可以把幾個 Validator 放到一個列表里面并傳入:

from attr import attrs, attrib,validators

def is_valid_gender(instance, attribute, value):
    if value not in ("M", "F"):
        raise ValueError(f"gender {value} is not valid")
        
def is_less_than_100(instance, attribute, value):
    if value > 100:
        raise ValueError(f"age {value} must less than 100")
        
@attrs
class Person:
    name = attrib(type = str)
    age = attrib(validator=[validators.instance_of(int), is_less_than_100])
    sex = attrib(validator=[validators.instance_of(str),is_valid_gender])

轉(zhuǎn)換器

很多時候我們會不小心傳入一些形式不太標(biāo)準(zhǔn)的結(jié)果,比如本來是 int 類型的 100,我們傳入了字符串類型的 100,那這時候直接拋錯應(yīng)該不好吧,所以我們可以設(shè)置一些轉(zhuǎn)換器來增強容錯機制,比如將字符串自動轉(zhuǎn)為數(shù)字:

from attr import attrs, attrib,validators

def to_int(value):
    try:
        return int(value)
    except:
        return None
@attrs
class Person:
    name = attrib(type = str)
    age = attrib(converter=to_int)
    sex = attrib(validator=validators.instance_of(str))

last_person = Person("xiaobai","35","M")    
print(last_person)

Out: Person(name="xiaobai", age=35, sex="M")
總結(jié)

這次我記錄了attrs 庫的用法,是參考了別人的文章,至此Python OOP 編程的個人學(xué)習(xí)經(jīng)歷都已經(jīng)記錄下來了

我的其他原創(chuàng)文章已經(jīng)放到了Github上,如果感興趣的朋友可以去看看,鏈接如下:

Python 精品練習(xí)題100道

Python 實用技巧匯總

Python Pandas教程

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/45200.html

相關(guān)文章

  • Python 面向對象編程OOP (五) 寫類神器:Dataclass

    摘要:大家好,上一期受到了朋友的啟發(fā),這一期我主要記錄一下我的的學(xué)習(xí)過程。 Dataclasses 大家好,上一期受到了朋友的啟發(fā),這一期我主要記錄一下我的Dataclasses的學(xué)習(xí)過程。 之前簡單回顧了attrs的用法,這一期來看更簡潔的自帶寫類神器:dataclasses,需要注意,版本要大于等于Python 3.7 官方文檔鏈接: Data Classes下面直接來看例子: 創(chuàng)建Da...

    elarity 評論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統(tǒng)的類繼承還要強大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評論0 收藏0
  • Python 面向對象編程OOP (一) 類,對象,屬性,訪問權(quán)限

    摘要:面向?qū)ο缶幊讨镁幊淌鞘裁创蠹液茫鳛樾“祝罱鼘W(xué)習(xí)了很多編程的知識,因為腦容量有限,特此一一按照學(xué)習(xí)順序記錄下來,如果哪里有錯誤,還請大神盡快指出,以免誤導(dǎo)他人。。。繼承也允許把一個派生類的對象作為一個基類對象對待。 Python面向?qū)ο缶幊讨?OOP編程是什么 大家好,作為小白,最近學(xué)習(xí)了很多Python OOP編程的知識,因為腦容量有限,特此一一按照學(xué)習(xí)順序記錄下來,如果哪里有...

    hiyayiji 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<