python:深度理解元類

提出問題:
如何在一個類創建一個類呢?

首先我們的實現方式是這樣的, 看下以下代碼:

class A :
    def create_class(self,user):
        if user=="company":
            class Company:
                def __str__(self):
                    return "Company class"
            return  Company
        if user=="school":
            class School:
                def __str__(self):
                    return "Company class"
            return  School

a=A()
Companyclass=a.create_class("company")
company=Companyclass()
print(company)       #  Company class

我們已經通過調用類的方法實現了 創建類,代碼比較簡單,我不做解釋.不會的直接@我.

雖然我們實現了,但是代碼量真是太大了. 我們再簡潔點也可以把 類A刪除掉,直接用方法就行了.

我們還有更好的方法直接創建類對象(類也是對象,方法和實例都可以稱爲對象)

Type 動態創建類

我們一定知道了,當我們調用type(1) 這個方法,可以進行類型查找. 它還有另外一個用法
就是創建類, 打個比喻 我們在做蛋糕, 必須用模板, 其中模板就是類,蛋糕是模板的實例.
但是蛋糕的模板 需要機器加工, 加工模板的機器就是 元類,它把模板當做機器的對象.

先看語法 :

Company=type(“類名稱”,(繼承的基類),{類的屬性 })

Company=type("Company",(),{})

print(Company)  #  <class '__main__.Company'>  

已經完成了 類的創建,只是繼承的基類和 類的屬性 全部爲空.

我們再進一步擴展添加一些屬性

Company=type("Company",(),{"name":"ebaotech","Adress":"楊浦區"})
co=Company()
print(co.name,co.Adress)  #ebaotech 楊浦區  

有細心的小夥伴該說了,類有屬性也有方法, 怎麼添加方法呢

我們就添加個方法試試 :

 def run(self):
    return "i am running"

Company=type("Company",(),{"name":"ebaotech","Adress":"楊浦區","run":run})
co=Company()
print(co.name,co.Adress,co.run())

解釋要點
1.run 方法裏必須有self ,不然用對象調用會找不到
2.“run”:run ,這個run 不要寫成 run()的形式

添加繼承基類

class Baseclass:
    def say(self):
        print("basecalss say")
def run(self):
    return "i am running"

Company=type("Company",(Baseclass,),{"name":"ebaotech","Adress":"楊浦區","run":run})
co=Company()
co.say()   #basecalss say 

注意點 在添加繼承類的時候,Baseclass 後邊要有逗號,否則會報錯.
自己寫的平常的類,和type 生成的類實際都是一樣的,平常的類也是會用type生成的.

這樣就完成了, 又引出一個概念,什麼是元類

元類就是創建類的類 ,剛纔的type 就是一個元類.
解釋下:既然我們已經介紹了,類也是對象 ,那誰去創建類對象呢,只能用元類.

元類控制過程

控制類對象生成過程用的是 metaclass 這個是在類對象生成之前進行的動作.

class Metaclass(type):
    pass

class A(metaclass=Metaclass):
    pass
    

爲什麼會控制類實例化過程呢 請看下邊的解釋.
Python做了如下的操作:
A中有metaclass這個屬性嗎?如果是,Python會在內存中通過__metaclass__創建一個名字爲Foo的類對象(我說的是類對象,請緊跟我的思路)。如果Python沒有找到__metaclass__,它會繼續在Metaclass(父類)中尋找__metaclass__屬性,並嘗試做和前面同樣的操作。如果Python在任何父類中都找不到__metaclass__,它就會在模塊層次中去尋找__metaclass__,並嘗試做同樣的操作。如果還是找不到__metaclass__,Python就會用內置的type來創建這個類對象。

一句話就是類裏有 metaclass 就是運行metaclass 類,實在找不到就用type 去生成 .

現在的問題就是,你可以在__metaclass__中放置些什麼代碼呢?答案就是:可以創建一個類的東西。那麼什麼可以用來創建一個類呢?type,或者任何使用到type或者子類化type的東東都可以, metaclass 也是繼承type .

自定義元類

請記住,'type’實際上是一個類,就像’str’和’int’一樣
所以,你可以從type繼承

class Metaclass(type):
    def __new__(cls, *args, **kwargs):
        return  super().__new__(cls, *args, **kwargs)

class A(metaclass=Metaclass):
    def __init__(self,name):
        self.name=name
    def __str__(self):
        return " i  love you "

a=A("Tengfei")

print(a)  #   i  love you 

class A 類對象操作實現委託給了 metaclass.

但就元類本身而言,它們其實是很簡單, metaclass 三部曲:

  1. 攔截類的創建 (metaclass)

  2. 修改類 (在new裏面修改)

  3. 返回修改之後的類 (return class )

具體的詳情可以參考一下的鏈接:
深度理解python 元類

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章