物件是python組織資料的形式,所有的資料都是物件(object),即某個類(class)的instance。即便是整數,甚至整數常量這種簡單的資料型別(其類為)。每個物件都有id(identity),型別(type)和值(value)。這三者中,只有value是可以變化的,另外兩個都是不可變的。
id可以被視為物件在記憶體中的位置,內嵌函式id()返回了物件的id,而is操作符則比較了兩個物件的id是否一致。type()返回了物件的型別(即所屬的類class):type(3)==int,除了常量之外(變數、類、包等)也可以用***.__class__得到同樣結果
而型別本身也是乙個物件,其型別是「type」:type(type(3))==type
"type"的所屬型別也是"type":type(type(type(3)))==type
某些物件包含了其他物件(的引用),它們被稱為容器(container),比如list,tuple,dict等,這些引用是容器的值的一部分。
下文中:類、型別、type、class同義
物件、例項、object、instance同義
(1)類的層次
物件的型別(type)即其所屬的類(class),這也決定了該物件所能支援的操作。內嵌函式type(object)可以得到物件所屬的類。
類的層次關係:nonetype:只有乙個物件,值唯一,即none
notimplementedtype:只有乙個物件,值唯一,即notimplemented
ellipsis:
numbers.number:numbers.integral:整數integers:即int型別
booleans:即bool型別
numbers.real:即float型別
numbers.complex:即complex型別
sequences:有序的有限元素的集合,其元素可以用非負整數索引(即從0開始)不可變sequences:建立之後不可修改strings:即str型別,可通過str.encode()函式編碼為bytes型別
tuples:即tuple,元組型別
bytes:即bytes型別,可通過bytes.decode()函式變為str型別
可變sequences:建立之後可以修改lists:即list型別
byte arrays:即bytearray型別,與bytes型別的區別在於可以修改
set型別:無序的,有限元素的集合,可len(),可iter()sets:可變集合,通過set()建立
frozen sets:不可變的集合,通過frozenset()建立,可hash()
callable型別:可呼叫的型別自定義函式:使用者通過def定義
例項方法:
generator函式:使用yield語句的函式
coroutine函式:協程函式
非同步generator函式:
built-in function:內嵌函式
built-in method:內嵌方法
class:就是類,所有的類都是可呼叫的,返回該類的物件
class instance:類的例項,可以通過實現__call__()來變得可呼叫
模組:python中的模組都是module類的物件
custom classes:
class instance:
i/o objects:
internal types:code objects:
frame objects:
traceback objects:
slice objects:
static method objects:
class method objects:
參考:3. data model - python 3.9.1 documentationdocs.python.org
(2)類==物件
定義某個類的乙個物件,可以用如下語句:
object = class(args...)
比如:a = int(4)
或者b = list([1,2,3])
由於python中所有的類也都是物件,因此這裡的class()相當於class.__call__(),即乙個object的可呼叫函式:
a = int.__call__(4)
b = list.__call__([1,2,3])
python中所有的類也都是物件,而這些物件的型別是type,或者說,所有類都是『type』的例項(包括type本身也是type的例項),如此一來,定義乙個新的類,相當於:
class = type(classname, superclass, attributedict)
或者class =type.__call__(classname, superclass, attributedict)
例如:class newclass:
data = 1
相當於:
newclass = type(「newclass」, (), )
相當於:
newclass = type.__call__(「newclass」, (), )
type被是乙個metaclass,即元類。
(3)metaclass
元類(metaclass)的物件是普通類,但是普通類的類可以不是『type』,也就時說除了『type』還可以定義其他的metaclass(通常這些metaclass的型別也是『type』)。
定義新的metaclass,並將類的元類設定為這個新metaclass的目的,通常是為了修改建立類的物件時的過程。
在類的定義中,通過宣告metaclass=mymeta,會使得:在生成類的時候,如果有,mymeta的__new__()和__init__()會被呼叫
在生成類的物件時,如果有,mymeta類的__call__()替代type.__call__()被呼叫:
例如:class foo(metaclass=mymeta)
會依次呼叫以下函式來建立foo:
1. type.__call__():mymeta的型別是『type』
(1) mymeta.__new__()
(2) mymeta.__init__()
foo = foo()
會依次呼叫如下函式來建立foo的例項foo:
1. mymeta.__call__()
(1) foo.__new__()
(2) foo.__init__()
注意混淆:
宣告某個類的元類在python3的用法是:
class foo(metaclass=mymeta)
在python2.7的用法則是如下:
class foo:
__metaclass__=mymeta
注意混淆:
注意區分「父類-子類」和「型別-物件」的關係,父類-子類能構成若干層的繼承結構,但是(在不指定metaclass的情況下)所有這些類的型別都是『type』,而子類和父類的元類可以不同,簡單來說,這是兩個不同維度的概念。
參考:somenzz:一文搞懂什麼是python的metaclasszhuanlan.zhihu.com
(4)生成例項的過程
我們知道,如果類foo的定義中有__call__函式的實現,則foo的物件foo是可以呼叫的,即:
foo()
相當於呼叫foo所屬類foo的__call__函式:
foo.__call__()
而當乙個類foo的物件foo生成的時候,發生的函式呼叫是這樣的:
foo = foo()
1. 呼叫foo的所屬型別的__call__:type.__call__()
(1) 呼叫foo的__new__函式:foo.__new__()
(2) 呼叫foo的__init__函式:foo.__init__()
當定義乙個metaclass mymeta的時候:
class mymeta(type):
相當於:
mymeta = type(「mymeta」, ...)
1. 呼叫type所屬型別(仍是type)的__call__:type.__call__()
(1) 呼叫type的__new__函式:type.__new__()
(2) 呼叫type的__init__函式:type.__init__()
當定義乙個metaclass為mymeta的類的時候:
class foo(metaclass=mymeta):
相當於:
bar = mymeta(「bar」, ...)
1. 呼叫mymeta所屬型別(type)的__call__函式:type.__call__()
(1) 呼叫mymeta的__new__函式:mymeta.__new__()
(2) 呼叫mymeta的__init__函式:mymeta.__init__()
當生成bar的物件bar的時候:
bar = bar()
1. 如果bar的所屬型別mymeta有定義__call__,則呼叫:mymeta.__call__()
(1) 如果其中呼叫了self.__new__函式,則呼叫:bar.__new__()
(2) 如果其中呼叫了self.__init__函式,則呼叫:bar.__init__()
2. 否則,則呼叫type.__call__()
(1) 呼叫type的__new__函式:type.__new__()
(2) 呼叫type的__init__函式:type.__init__()
宣告類和定義物件
class date private,public稱之為成員訪問限定符,此外還有protect。被宣告為private 私有成員 只能被本類中的成員函式引用,而public 公用成員 可以被本類的成員所引用,也可以被類外函式引用,protect宣告的為受保護的成員,不能被類外訪問,但可以被派生類的成...
用父類宣告物件和用子類宣告物件
class father class son extends father class test 首先都是訪問本身類的東西 方法與屬性 的.父類定義就呼叫父類的,子類定義的話就呼叫子類的 當乙個父類定義的變數引用乙個子類例項時,呼叫乙個方法時,這個方法將會呼叫子類,因為方法被覆蓋.情況就特殊在父類定...
Python類和物件
1 建立類 語法 class classname 類的幫助資訊 類文件字串 class suite 類體 例如 class employee 所有員工的基類 empcount 0 def init self,name,salary self.name name self.salary salary ...