python type()函數(shù)專題——?jiǎng)討B(tài)創(chuàng)建類

2023-04-20 18:01 更新

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

簡(jiǎn)介

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

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

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

說人話,就是返回這個(gè)對(duì)象的類型,舉個(gè)例子:

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的實(shí)例對(duì)象  (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']

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

 所有的動(dòng)物都會(huì)呼吸??!

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

讓我們?cè)賮砜纯吹诙N語法:

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

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

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

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

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

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的實(shí)例對(duì)象  (aka 'object') 或者 <class '__main__.Animal'>)
print(dir(a))
  
People = type("People",(Animal,) , {'sex':'M'}) # 我們定義了一個(gè)新類叫People,他繼承于animal類,多了一個(gè)新的屬性sex

human = People('男人')

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

運(yùn)行結(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)建了一個(gè)Animal類的子類People,這個(gè)子類相比父類多了一個(gè)sex方法。

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

dict參數(shù)是一個(gè)字典,字典內(nèi)不能寫函數(shù),但我們可以先定義一個(gè)函數(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的實(shí)例對(duì)象  (aka 'object') 或者 <class '__main__.Animal'>)
print(dir(a))
  
People = type("People",(Animal,) , {'sex':'M'}) # 我們定義了一個(gè)新類叫People,他繼承于animal類,多了一個(gè)新的屬性sex

human = People('男人')

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



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

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

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

運(yùn)行結(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類中了!

同時(shí)這個(gè)fly()方法也工作正常。

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

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

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

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

總結(jié)

通過type添加的屬性是類屬性,并不是實(shí)例屬性

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

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

對(duì)元類的理解與注意事項(xiàng)

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

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

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

str = "W3cschool"

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

運(yùn)行結(jié)果如下:

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


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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)