python宣告類和物件 Python中的類和物件

2021-10-13 05:44:35 字數 4681 閱讀 1126

物件是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 documentation​docs.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的metaclass​zhuanlan.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 ...