python type()函數(shù)專題——動態(tài)創(chuàng)建類

2023-04-20 18:01 更新

我們知道,?type()?函數(shù)是python的內(nèi)置函數(shù),可以用來查看變量的類型,它是小編最常用的一個函數(shù)。小編之所以如此中意他并不僅僅是因為它只有四個字母,在使用上比?isinstance()?輸入更快,還因為使用?type()?可以直接看到變量的類型,而使用?isinstance()?需要先知道大概是什么類型,才能判斷是不是這個類型,從直觀程度上?type()?更加直觀。它也成為小編手冊示例代碼的優(yōu)選函數(shù)之一。但是?type()?函數(shù)的作用不止于此,今天這篇文章我們就來重溫一下?type(?)函數(shù)的功能吧。

簡介

?type()?函數(shù)有兩種語法,分別是:

type(object)
#或者
type(name, bases, dict, **kwds)

前一種用法接受一個對象(變量),返回 object 的類型。 返回值是一個 type 對象,通常與 ?object.__class__ ?所返回的對象相同。

說人話,就是返回這個對象的類型,舉個例子:

class Animal():
    name = ""
    def __init__(self,name):
        self.name = name
    def get_name(self):
        return self.name  
    def breathe():
        print("我可以呼吸")


a = Animal('大象')
print(type(a))            # 返回類Animal的實例對象  (aka 'object') 或者 <class '__main__.Animal'>)
print(dir(a))

他的返回值是:

<class '__main__.Animal'>

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'get_name', 'name']

我們可以看出,這是一個Animal對象。它有一個name屬性和兩個方法(get_name()和breathe())

 所有的動物都會呼吸??!

動態(tài)創(chuàng)建類

讓我們再來看看第二種語法:

type(name, bases, dict, **kwds)

這個時候?type()?函數(shù)可以傳入三個參數(shù),第一個參數(shù)name是我們要創(chuàng)建的類的類名,第二個參數(shù)bases為這個類繼承于誰(也就是誰是他的父類),如果為空的話則繼承于object類,第三個參數(shù)dict是一個字典,包含類的屬性和方法定義。

 注意,bases參數(shù)必須是一個元組,所以要使用元組的形式把參數(shù)傳進(jìn)去!

創(chuàng)建一個子類,增加新的屬性

前面我們提到dict參數(shù)可以給新的子類添加新的屬性和方法定義,來看看這個例子:

class Animal():
    name = ""
    def __init__(self,name):
        self.name = name
    

    def get_name(self):
        return self.name 
    
    
    def breathe():
        print("我可以呼吸")


a = Animal('大象')
print(type(a))            # 返回類Animal的實例對象  (aka 'object') 或者 <class '__main__.Animal'>)
print(dir(a))
  
People = type("People",(Animal,) , {'sex':'M'}) # 我們定義了一個新類叫People,他繼承于animal類,多了一個新的屬性sex

human = People('男人')

print(type(human))            # 返回類People的實例對象 <class '__main__.People'>)
print(dir(human))

運行結(jié)果如下:

<class '__main__.Animal'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'get_name', 'name']
<class '__main__.People'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'get_name', 'name', 'sex']

可以看到我們成功地創(chuàng)建了一個Animal類的子類People,這個子類相比父類多了一個sex方法。

創(chuàng)建一個子類,增加新的方法

dict參數(shù)是一個字典,字典內(nèi)不能寫函數(shù),但我們可以先定義一個函數(shù),然后將函數(shù)名作為字典的值傳進(jìn)去:

class Animal():
    name = ""
    def __init__(self,name):
        self.name = name
    

    def get_name(self):
        return self.name 
    
    
    def breathe():
        print("我可以呼吸")


a = Animal('大象')
print(type(a))            # 返回類Animal的實例對象  (aka 'object') 或者 <class '__main__.Animal'>)
print(dir(a))
  
People = type("People",(Animal,) , {'sex':'M'}) # 我們定義了一個新類叫People,他繼承于animal類,多了一個新的屬性sex

human = People('男人')

print(type(human))            # 返回類People的實例對象 <class '__main__.People'>)
print(dir(human))



def fly(self):
    print("我可以飛")

Bird = type('Bird', (Animal,), {'fly': fly})

bird =Bird('烏鴉')
print(type(bird))            # 返回類People的實例對象 <class '__main__.People'>)
print(dir(bird))
bird.fly()

運行結(jié)果如下:

<class '__main__.Animal'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'get_name', 'name']
<class '__main__.People'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'get_name', 'name', 'sex']
<class '__main__.Bird'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'breathe', 'fly', 'get_name', 'name']
我可以飛

可以看到,我們成功的將fly方法添加到了Animal類的子類Bird類中了!

同時這個fly()方法也工作正常。

python中類創(chuàng)建的本質(zhì)

我們使用class創(chuàng)建類,當(dāng)你使用class關(guān)鍵字時,Python解釋器自動創(chuàng)建這個對象。而底層其實使用的是type函數(shù)(type函數(shù)也可以查看實例所屬類型)來創(chuàng)建類的。所以我們可以直接使用type()函數(shù)來手動實現(xiàn)動態(tài)創(chuàng)建類。

當(dāng)type()只有一個參數(shù)時,其作用就是返回變量或?qū)ο蟮念愋彤?dāng)type()有三個參數(shù)時,其作用就是創(chuàng)建類對象:

  • 第一個參數(shù):name表示類名稱,字符串類型
  • 第二個參數(shù):bases表示繼承對象(父類),元組類型,單元素使用逗號
  • 第三個參數(shù):attr表示屬性,這里可以填寫類屬性、類方式、靜態(tài)方法,采用字典格式,key為屬性名,value為屬性值

總結(jié)

通過type添加的屬性是類屬性,并不是實例屬性

通過type可以給類添加普通方法,靜態(tài)方法,類方法,效果跟class一樣

type創(chuàng)建類的效果,包括繼承等的使用性質(zhì)和class創(chuàng)建的類一樣。本質(zhì)class創(chuàng)建類的本質(zhì)就是用type創(chuàng)建。所以可以說python中所有類都是type創(chuàng)建的。

對元類的理解與注意事項

元類就是類的類,python中函數(shù)type實際上是一個元類。type就是Python在背后用來創(chuàng)建所有類的元類。Python中所有的東西——都是對象。這包括整數(shù)、字符串、函數(shù)以及類。它們?nèi)慷际菍ο?,而且它們都是從一個類創(chuàng)建而來,這個類就是type。type就是Python的內(nèi)建元類,當(dāng)然了,也可以創(chuàng)建自己的元類。

python查看對象所屬類型既可以用type函數(shù),也可以用對象自帶的__class__屬性。

以下代碼驗證:任何對象最終的所屬類都是type。 type是所有類的創(chuàng)造者。

str = "W3cschool"

print(type(str))
print(type(type(str)))

運行結(jié)果如下:

<class 'str'>
<class 'type'>


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號