日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

python类的应用_Python · 元类(Meta Class)及其应用

發布時間:2025/3/15 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python类的应用_Python · 元类(Meta Class)及其应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

(這里是本章用到的 GitHub 地址)萬物皆對象 —— Python

本章所介紹的元類(Meta Class)和之前介紹過的裝飾器(Decorator)都是上面這句話的具現,其中裝飾器告訴過我們“函數亦對象”,元類則會告訴我們“類亦對象”

Meta Class 是傳說中的黑魔法、黑魔法中的戰斗機(……)。我其實對它也只一知半解,所以以下說的內容可能僅展現了它神奇功用的冰山一角。不過作為一個入門教程來說的話、可能會剛剛好也說不定(其實只是在為自己的弱小找借口)(喂)

所謂的“類亦對象”和“函數亦對象”的思想類似:它意味著類可以被賦值給變量、通過變量也能創建該類的實例。舉個栗子:

class Class:

def __init__(self):

self.x = 1

one = Class

print(one().x)

Out[1]:

1

正如裝飾器返回的是一個函數,我們可以認為元類返回的是一個類。 也正如我在講裝飾器里說過的,裝飾器的核心思想,就是裝飾函數這個對象、讓函數自身代碼不變的情況下、增添一些具有普適性的功能。在我看來,元類的核心思想,就是搗鼓類這個對象、使你能對其有著最高程度的控制權。

注意:這絕不一定是個準確的理解!正如 Python界的領袖 Tim Peters 說過:元類就是深度的魔法,99%的用戶應該根本不必為此操心。如果你想搞清楚究竟是否需要用到元類,那么你就不需要它。那些實際用到元類的人都非常清楚地知道他們需要做什么,而且根本不需要解釋為什么要用元類。

我的理解僅僅來自于我對元類的應用,它很有可能是非常片面的。不過,由于我的目的是為了讓大家知道元類的一種可能是最簡單的使用姿勢、使大家不至于看到代碼里面的 metaclass 就怕,所以還請觀眾老爺們允許我這個半吊子繼續用這個理解講下去(如果有觀眾老爺有更深更好的理解、歡迎在評論區里面教我、我會把它們貼在這里的 ( σ'ω')σ)

那么什么叫做最高程度的控制權呢?一個比較簡單的栗子就是實現如下需求:定義一個“人”(Person)類,它有三個方法:吃飯、睡覺、續幾秒(咦)

定義 Person 的三個子類“小張”(Zhang)、“小王”(Wang)、“小江”(Jiang)

定義“人”的子類“小紅”(Hong), 要求他:吃飯像小張一樣快

睡覺像小王一樣香

續秒像小江一樣熟練(喂)

你會怎么去實現呢?如果再要求你把上面三個要求換一換順序呢?

也許 Python 有許多其它的解決方案、但(我所知道的)最簡單的方法、就是使用元類了

幸運的是,雖然元類的思想可能很深,但就這個簡單的問題而言、即使我不進行任何說明、相信聰明的觀眾老爺們也能讀懂下面這幾塊代碼

先定義 Person 類:

class Person:

def __init__(self):

self.ability = 1

def eat(self):

print("Eat: ", self.ability)

def sleep(self):

print("Sleep: ", self.ability)

def save_life(self):

print("+ ", self.ability, " s")

再定義三個子類:

class Wang(Person):

def eat(self):

print("Eat: ", self.ability * 2)

class Zhang(Person):

def sleep(self):

print("Sleep: ", self.ability * 2)

class Jiang(Person):

def save_life(self):

print("+ inf s")

然后是最關鍵的、定義元類(Meta Class):

class Mixture(type):

def __new__(mcs, *args, **kwargs):

name, bases, attr = args[:3]

person1, person2, person3 = bases

def eat(self):

person1.eat(self)

def sleep(self):

person2.sleep(self)

def save_life(self):

person3.save_life(self)

attr["eat"] = eat

attr["sleep"] = sleep

attr["save_life"] = save_life

return type(name, bases, attr)

Done!可能會有觀眾老爺發現其中有三行代碼顯得“特別傻”——沒錯,確實可以用更具有普適性的三行代碼來代替我們上面倒數第二到第四行的代碼:

class Mixture(type):

def __new__(mcs, *args, **kwargs):

name, bases, attr = args[:3]

person1, person2, person3 = bases

def eat(self):

person1.eat(self)

def sleep(self):

person2.sleep(self)

def save_life(self):

person3.save_life(self)

for key, value in locals().items():

if str(value).find("function") >= 0:

attr[key] = value

return type(name, bases, attr)

拋開所有技術細節而只談應用的話、其實上面這個栗子可能已經相當足夠了。接下來就讓我們測試一下這個 Mixture元類吧。先來定義一個小的測試函數,它依次調用 Person 實例吃飯、睡覺、續幾秒這三個動作:

def test(person):

person.eat()

person.sleep()

person.save_life()

然后進行兩組測試:

class Hong(Wang, Zhang, Jiang, metaclass=Mixture):

pass

test(Hong())

Out[2]:

Eat: 2

Sleep: 2

+ inf s

class Hong(Zhang, Wang, Jiang, metaclass=Mixture):

pass

test(Hong())

Out[3]:

Eat: 1

Sleep: 1

+ inf s

Done!可以看到、我們確實獲得了類的高度控制權

可能會有觀眾老爺想問,如果我直接繼承會發生什么事情?就這個栗子而言,如果定義一個類直接繼承小王、小張、小江的話,無論按什么順序繼承、結果都會是一樣的(猜猜這個結果會是什么? ( σ'ω')σ)

值得一提的是,可以看到我們定義的元類繼承自 type、這是因為 Python 自帶的元類就是 type

其實即使僅僅基于上述栗子的思想、就已經可以搗鼓出許多有意思的應用了。在我自己實現的神經網絡中、我就用了這個思想來把普通 NN 里面的附加層(Dropout、Normalize)擴展成了 CNN 里面的附加層,感興趣的觀眾老爺們可以看看這里面的 ConvSubMeta 類

我沒有講太多原理層面的東西,一方面是因為我覺得知道怎么用就好、另一方面是因為我怕亂說話遭報應(……)

希望觀眾老爺們能夠喜歡~

總結

以上是生活随笔為你收集整理的python类的应用_Python · 元类(Meta Class)及其应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。