日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

python中的枚舉類和元類

 印度阿三17 2019-09-14

當(dāng)我們需要定義常量時(shí),一個(gè)辦法是用大寫變量通過整數(shù)來定義,例如月份:

JAN = 1
FEB = 2
MAR = 3
...
NOV = 11
DEC = 12

好處是簡單,缺點(diǎn)是類型是int,并且仍然是變量。
更好的方法是為這樣的枚舉類型定義一個(gè)class類型,然后,每個(gè)常量都是class的一個(gè)唯一實(shí)例。Python提供了Enum類來實(shí)現(xiàn)這個(gè)功能:

from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

這樣我們就獲得了Month類型的枚舉類,可以直接使用Month.Jan來引用一個(gè)常量,或者枚舉它的所有成員:

for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

value屬性則是自動(dòng)賦給成員的int常量,默認(rèn)從1開始計(jì)數(shù)。
如果需要更精確地控制枚舉類型,可以從Enum派生出自定義類:

from enum import Enum, unique

@unique
class Weekday(Enum):
    Sun = 0 # Sun的value被設(shè)定為0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

@unique裝飾器可以幫助我們檢查保證沒有重復(fù)值。
訪問這些枚舉類型可以有若干種方法:

>>> day1 = Weekday.Mon
>>> print(day1)
Weekday.Mon
>>> print(Weekday.Tue)
Weekday.Tue
>>> print(Weekday['Tue'])
Weekday.Tue
>>> print(Weekday.Tue.value)
2
>>> print(day1 == Weekday.Mon)
True
>>> print(day1 == Weekday.Tue)
False
>>> print(Weekday(1))
Weekday.Mon
>>> print(day1 == Weekday(1))
True
>>> Weekday(7)
Traceback (most recent call last):
  ...
ValueError: 7 is not a valid Weekday
>>> for name, member in Weekday.__members__.items():
...     print(name, '=>', member)
...
Sun => Weekday.Sun
Mon => Weekday.Mon
Tue => Weekday.Tue
Wed => Weekday.Wed
Thu => Weekday.Thu
Fri => Weekday.Fri
Sat => Weekday.Sat

可見,既可以用成員名稱引用枚舉常量,又可以直接根據(jù)value的值獲得枚舉常量。
Enum可以把一組相關(guān)常量定義在一個(gè)class中,且class不可變,而且成員可以直接比較。
比較好的講解
https://segmentfault.com/a/1190000017327003
元類
動(dòng)態(tài)語言和靜態(tài)語言最大的不同,就是函數(shù)和類的定義,不是編譯時(shí)定義的,而是運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建的。
比方說我們要定義一個(gè)Hello的class,就寫一個(gè)hello.py模塊:

class Hello(object):
    def hello(self, name='world'):
        print('Hello, %s.' % name)

當(dāng)Python解釋器載入hello模塊時(shí),就會(huì)依次執(zhí)行該模塊的所有語句,執(zhí)行結(jié)果就是動(dòng)態(tài)創(chuàng)建出一個(gè)Hello的class對象,測試如下:

>>> from hello import Hello
>>> h = Hello()
>>> h.hello()
Hello, world.
>>> print(type(Hello))
<class 'type'>
>>> print(type(h))
<class 'hello.Hello'>

type()函數(shù)可以查看一個(gè)類型或變量的類型,Hello是一個(gè)class,它的類型就是type,而h是一個(gè)實(shí)例,它的類型就是class Hello。
我們說class的定義是運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建的,而創(chuàng)建class的方法就是使用type()函數(shù)。
type()函數(shù)既可以返回一個(gè)對象的類型,又可以創(chuàng)建出新的類型,比如,我們可以通過type()函數(shù)創(chuàng)建出Hello類,而無需通過class Hello(object)…的定義:

>>> def fn(self, name='world'): # 先定義函數(shù)
...     print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 創(chuàng)建Hello class
>>> h = Hello()
>>> h.hello()
Hello, world.
>>> print(type(Hello))
<class 'type'>
>>> print(type(h))
<class '__main__.Hello'>

要?jiǎng)?chuàng)建一個(gè)class對象,type()函數(shù)依次傳入3個(gè)參數(shù):
class的名稱;
繼承的父類集合,注意Python支持多重繼承,如果只有一個(gè)父類,別忘了tuple的單元素寫法;
class的方法名稱與函數(shù)綁定,這里我們把函數(shù)fn綁定到方法名hello上。

通過type()函數(shù)創(chuàng)建的類和直接寫class是完全一樣的,因?yàn)镻ython解釋器遇到class定義時(shí),僅僅是掃描一下class定義的語法,然后調(diào)用type()函數(shù)創(chuàng)建出class。
正常情況下,我們都用class Xxx…來定義類,但是,type()函數(shù)也允許我們動(dòng)態(tài)創(chuàng)建出類來,也就是說,動(dòng)態(tài)語言本身支持運(yùn)行期動(dòng)態(tài)創(chuàng)建類,這和靜態(tài)語言有非常大的不同,要在靜態(tài)語言運(yùn)行期創(chuàng)建類,必須構(gòu)造源代碼字符串再調(diào)用編譯器,或者借助一些工具生成字節(jié)碼實(shí)現(xiàn),本質(zhì)上都是動(dòng)態(tài)編譯,會(huì)非常復(fù)雜。
metaclass
除了使用type()動(dòng)態(tài)創(chuàng)建類以外,要控制類的創(chuàng)建行為,還可以使用metaclass。
metaclass,直譯為元類,簡單的解釋就是:
當(dāng)我們定義了類以后,就可以根據(jù)這個(gè)類創(chuàng)建出實(shí)例,所以:先定義類,然后創(chuàng)建實(shí)例。
但是如果我們想創(chuàng)建出類呢?那就必須根據(jù)metaclass創(chuàng)建出類,所以:先定義metaclass,然后創(chuàng)建類。
連接起來就是:先定義metaclass,就可以創(chuàng)建類,最后創(chuàng)建實(shí)例。
所以,metaclass允許你創(chuàng)建類或者修改類。換句話說,你可以把類看成是metaclass創(chuàng)建出來的“實(shí)例”。
metaclass是Python面向?qū)ο罄镒铍y理解,也是最難使用的魔術(shù)代碼。正常情況下,你不會(huì)碰到需要使用metaclass的情況,所以,以下內(nèi)容看不懂也沒關(guān)系,因?yàn)榛旧夏悴粫?huì)用到。
我一個(gè)小白看這些真是有夠?yàn)殡y的,直接貼鏈接了,以后有機(jī)會(huì)用到再來看
https://www./wiki/1016959663602400/1017592449371072

來源:https://www./content-1-451551.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多