零基礎入門python3.7 ——基礎知識總結(二十五)type()動態創建類和MetaClass元類

type()這個內置函數不僅可以檢查數據類型。還可以創建一個類,

一。type()函數的用法

  • 檢查數據類型
a = 1000
print(type(a))

b = 'python'
print(type(b))

<class 'int'>
<class 'str'>
  • 創建類。可以接受三個參數。第一個參數表示要創建的類名。第二個參數是一個元祖用於儲存要創建類的父類。 第三個參數爲字典 儲存類內定義的屬性和方法。
class Person:
    name = "jack"
    city = "成都"

person = type("Person1", (Person,), {"name": "alice", "age": 3})

print(person.name)
print(person.age)
print(person.city)

alice
3
成都
  • type()在創建類時函數的三個參數是必要的。 否則會拋出異常
class Person:
    name = "jack"
    city = "成都"

person = type("Person1", {"name": "alice", "age": 3})

print(person.name)
print(person.age)
print(person.city)

Traceback (most recent call last):
  File "/Users/apple/Documents/重要文件/python3/python21.py", line 5, in <module>
    person = type("Person1", {"name": "alice", "age": 3})
TypeError: type() takes 1 or 3 arguments
  • 父類只有一個元素的首個元素後必須加逗號。否則會拋出異常
class Person:
    name = "jack"
    city = "成都"

person = type("Person1", (Person ),{"name": "alice", "age": 3})

print(person.name)
print(person.age)
print(person.city)

Traceback (most recent call last):
  File "/Users/apple/Documents/重要文件/python3/python21.py", line 5, in <module>
    person = type("Person1", (Person ),{"name": "alice", "age": 3})
TypeError: type.__new__() argument 2 must be tuple, not type
  • 所有類默認繼承的是object
person = type("Person1", (object,),{"name": "alice", "age": 3})

print(person.name)
print(person.age)

alice
3

二。MetaClass元類

元類本身就是一個類。但是相對於普通類而言可以動態的修改類屬性和類方法。爲了使元類使用起來方便一般是先創建元類。然後在用元類去創建類,最後在實例化,要想把一個類設計成元類是有條件的。

  • 必須顯示的繼承自type類 
  • 類中補虛要實現且定義__new__()方法。而且該方法必須要返回一個該類的實例對象。原因在於在使用元類創建類時。該__new__()方法會自動執行。用於修改新的類。

__new__()方法同時還自帶四個參數

  • cls表示動態修改的類
  • name表示動態修改的類名
  • bases表示被動態修改的類的所有父類
  • attrs表示被動態修改的類的所有屬性和方法組成的字典
class Person(type):
    def __new__(cls, name, bases, attrs):
        attrs["name"] = "小王"
        attrs["getName"] = lambda self: self.name
        return  super().__new__(cls, name, bases, attrs)
  • 因爲元類的__new__()中手動添加了新的屬性和方法那麼也就意味着通過元類創建的類會添加額外的屬性和方法
class Person(type):
    def __new__(cls, name, bases, attrs):
        attrs["name"] = "小王"
        attrs["getName"] = lambda self: self.name
        return  super().__new__(cls, name, bases, attrs)

class Person1(object, metaclass=Person):
    pass

a = Person1()
print(a.name)
print(a.getName())

小王
小王
  • 不難發現元類不單單可以創建一個類。是可以創建多個類的
class Person(type):
    def __new__(cls, name, bases, attrs):
        attrs["name"] = "小王"
        attrs["getName"] = lambda self: self.name
        return  super().__new__(cls, name, bases, attrs)

class Person1(object, metaclass=Person):
    pass

class Person2(object,metaclass= Person):
    pass

a = Person1()
print(a.name)
print(a.getName())

b = Person2()
print(b.name)
print(b.getName())

小王
小王
小王
小王
  • 在通過元類創建類時必須通過metaclass=“類名”指定元類
class Person(type):
    def __new__(cls, name, bases, attrs):
        attrs["name"] = "小王"
        attrs["getName"] = lambda self: self.name
        return  super().__new__(cls, name, bases, attrs)

class Person2(metaclass= Person):
    pass

b = Person2()
print(b.name)
print(b.getName())

小王
小王

 

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