Python 學習之元類

1. 使用 type() 動態創建類

Python 是動態語言。

動態語言和靜態語言最大的不同,就是函數和類的定義,不是編譯時定義的,而是運行時動態創建的。

首先我們新建一個 hello.py 的模塊,然後定義一個 Hello 的 class

class Hello(object):
    def hello(self, name='Py'):
        print('Hello,', name)

然後在另一個模塊中引用 hello 模塊,並輸出相應的信息。

其中 type() 函數的作用是可以查看一個類型和變量的類型。

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

from com.kevin.hello import Hello

h = Hello()
h.hello()

print(type(Hello))
print(type(h))

結果:

Hello, Py
<class 'type'>
<class 'com.kevin.hello.Hello'>

type() 函數可以查看一個類型或變量的類型,Hello 是一個 class ,它的類型就是 type ,而 h 是一個實例,它的類型就是 com.kevin.hello.Hello。

其實 type() 函數不僅可以返回一個對象的類型,也可以創建出新的類型。

我們可以通過 type() 函數創建出上面例子中的 Hello 類

# -*- coding: UTF-8 -*-

def printHello(self, name='Py'):
    # 定義一個打印 Hello 的函數
    print('Hello,', name)


# 創建一個 Hello 類
Hello = type('Hello', (object,), dict(hello=printHello))

# 實例化 Hello 類
h = Hello()
# 調用 Hello 類的方法
h.hello()
# 查看 Hello class 的類型
print(type(Hello))
# 查看實例 h 的類型
print(type(h))

結果:

Hello, Py
<class 'type'>
<class '__main__.Hello'>

通過 type() 函數創建 class 對象的參數說明:

1、class 的名稱,比如例子中的起名爲 Hello

2、繼承的父類集合,注意 Python 支持多重繼承,如果只有一個父類,tuple 要使用單元素寫法;例子中繼承 object 類,因爲是單元素的 tuple ,所以寫成 (object,)

3、class 的方法名稱與函數綁定;例子中將函數 printHello 綁定在方法名 hello 中

元類

除了使用type()動態創建類以外,要控制類的創建行爲,還可以使用metaclass。

metaclass,直譯爲元類,簡單的解釋就是:

當我們定義了類以後,就可以根據這個類創建出實例,所以:先定義類,然後創建實例。

但是如果我們想創建出類呢?那就必須根據metaclass創建出類,所以:先定義metaclass,然後創建類。

連接起來就是:先定義metaclass,就可以創建類,最後創建實例。

所以,metaclass允許你創建類或者修改類。換句話說,你可以把類看成是metaclass創建出來的“實例”。

metaclass是Python面向對象裏最難理解,也是最難使用的魔術代碼。正常情況下,你不會碰到需要使用metaclass的情況,所以,以下內容看不懂也沒關係,因爲基本上你不會用到。

  1. 實例:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# metaclass是創建類,所以必須從`type`類型派生:
class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['add'] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)

# 指示使用ListMetaclass來定製類
class MyList(list, metaclass=ListMetaclass):
    pass

L = MyList()
L.add(1)
L.add(2)
L.add(3)
L.add('END')
print(L)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章