Python3基础教程:元类详解
1.引入
Python中一切皆對象,所謂對象就是由類創建出來,那么創建對象的類本身也是一個對象,也就是說創建對象的類本身也由別的什么類創建,這種創建類的類就叫元類.
2.元類是誰?
type函數就是元類,沒錯就是那個打印數據類型的函數,也就是說是type創建了類.
我們寫一個類然后打印一下他的屬性看看
In [4]: class MyClass(object): ...: pass ...: In [5]: type(MyClass) Out[5]: type可以看到MyClass類的類型是type,用Python語言來描述這種關系就是:
MyClass = type()3.type和object的區別
剛接觸元類時很容易搞混這兩者.區別如下
type是說有類的創建者
object是所有類的父類
怎么理解呢?記住以下幾點就OK了(可能有點繞)
- type和object不是同一層的東西
- type是元類object是普通類
- 元類的對象是普通類,普通類的對象就是普通對象
- 繼承自object的類包括object本身都是普通類
- 繼承自type的類都是元類
- 普通類都是元類的對象
那么是誰創建了type呢?這個問題留給你們自己去找答案,我相信有很多小伙伴已經猜到了.
4.通過type創建普通類
由type創建普通類的格式為
變量名 = type("類名", ("繼承的類",), {"屬性名":"屬性值"})第二個參數是元組類型
舉個例子
In [11]: Myclass = type("ClassName", (object,), {"name": "kainhuck", "foo":"bar"}) In [12]: Myclass Out[12]: __main__.ClassName可以看到Myclass不是真正的類名,真正的類名是ClassName.
創建一個名為ClassA,繼承自object類,并帶有屬性name和方法printName的類,寫法如下
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' In [15]: def printName(self): ...: print(self.name) ...: In [16]: ClassA = type("ClassA",(object,),{"name":"myName", "printName":printName}) In [17]: a = ClassA() In [18]: a.printName() myName5.創建自己的元類
前面已經有過提示,我們可以通過繼承type來創建自己的元類
舉個例子:
In [20]: class MetaClass(type): ...: pass ...: In [21]: ClassA = MetaClass("ClassA",(object,),{"name":"myName", "printName":printName}) In [22]: a = ClassA() In [23]: a.printName() myName這個例子中我只繼承type沒有增加任何新的功能
我們知道創建一個對象的功能由__new__函數實現,下面我們通過修改__new__函數來創建一個必須含有printName方法的類.
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' In [30]: class MyMetaClass(type): ...: def __new__(cls, name, bases, attrs): ...: func = attrs.get("printName", None) ...: if not callable(func): ...: raise NotImplementedError("必須創建一個名為 printName 的函數") ...: return type.__new__(cls, name, bases, attrs) ...: ...: In [31]: ClassA = MyMetaClass("ClassA",(object,),{"name":"myName", "printName":"not callable"}) --------------------------------------------------------------------------- NotImplementedError Traceback (most recent call last) <ipython-input-31-772aa102a27f> in <module> ----> 1 ClassA = MyMetaClass("ClassA",(object,),{"name":"myName", "printName":"not callable"})<ipython-input-30-c2ffcc442a77> in __new__(cls, name, bases, attrs)3 func = attrs.get("printName", None)4 if not callable(func): ----> 5 raise NotImplementedError("必須創建一個名為 printName 的函數")6 return type.__new__(cls, name, bases, attrs)7 NotImplementedError: 必須創建一個名為 printName 的函數In [32]: ClassA = MyMetaClass("ClassA",(object,),{"name":"myName", "printName":printName}) In [33]:可以看到如果我們定義的類沒有創建printName函數就會報錯.
6.類工廠
所謂類工廠就是生產類的地方,我們可以設計一個函數,使該函數可以通過參數來返回不同的類.
男人和女人都是人,但是不同性別的人剪頭發的時間不一樣.我們就可以定義一個類工廠來按需求產生不同的類.
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def Person(sex):def manCut(self):print("我是男人,我剪頭發很快")def womanCut(self):print("我是女人,我剪頭發很慢")if sex == "man":return type("man", (object,), {"hairCut": manCut})elif sex == "woman":return type("woman", (object,), {"hairCut": womanCut})else:print("Error")Man = Person("man") Woman = Person("woman")lilei = Man() hanmeimei = Woman()輸出:
我是男人,我剪頭發很快 我是女人,我剪頭發很慢總結
以上是生活随笔為你收集整理的Python3基础教程:元类详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python3基础教程:可变参数和关键字
- 下一篇: Python高效编程技巧