W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
我們知道,?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())
所有的動物都會呼吸??!
讓我們再來看看第二種語法:
type(name, bases, dict, **kwds)
這個時候?type()
?函數(shù)可以傳入三個參數(shù),第一個參數(shù)name是我們要創(chuàng)建的類的類名,第二個參數(shù)bases為這個類繼承于誰(也就是誰是他的父類),如果為空的話則繼承于object類,第三個參數(shù)dict是一個字典,包含類的屬性和方法定義。
注意,bases參數(shù)必須是一個元組,所以要使用元組的形式把參數(shù)傳進(jìn)去!
前面我們提到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方法。
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()方法也工作正常。
我們使用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)建類對象:
通過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'>
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: