python 编程模型
數(shù)據(jù)模型(譯)
image.png1 對(duì)象(object)、類型(type)和值(value)
python中所有的數(shù)據(jù)都是通過對(duì)象(object)或者對(duì)象之間的關(guān)系來(lái)表示
每個(gè)對(duì)象(object)都有ID、類型(type)和數(shù)值(value)
一旦對(duì)象創(chuàng)建,它的ID便固定不變,可以理解成對(duì)象存放在內(nèi)存中的地址;is操作就是比較兩個(gè)對(duì)象的ID,而id()函數(shù)則是返回對(duì)象ID的整數(shù)表達(dá)式
對(duì)象的類型(type)決定了對(duì)象的行為,以及決定對(duì)象可能的值(value);type()函數(shù)返回對(duì)象的類型(type本身也是對(duì)象);類似于ID,對(duì)象的類型一般情況下也是不可變的
部分對(duì)象的值(value)是可變的,我們稱之為可變類型(mutable);部分對(duì)象的值是不可變的,我們稱這為不可變類型(immutable);當(dāng)一個(gè)不可變?nèi)萜?#xff08;如tuple)包含可變類型的對(duì)象引用,雖然引用對(duì)象的值可以改變,但我們依然認(rèn)為此容器的值不是可變的,因?yàn)槿萜鞅旧戆膶?duì)象不可變,所以嚴(yán)格來(lái)講,不可變類型并不意味著數(shù)值(value)不可更改。對(duì)象是否可變由類型決定,比如數(shù)字(numbers)、字符串(strings)和元組(tuples)是不可變的;字典(dictionaries)和列表(lists)是可變的
對(duì)象從不顯示地銷毀,當(dāng)沒有引用指向這些對(duì)象時(shí),它們就可能被回收(GC)
注意,try...except語(yǔ)句會(huì)使對(duì)象保持存活
有些對(duì)象指向外部資源,如打開的文件或窗口;當(dāng)對(duì)象被回歸時(shí),資源也一并釋放。然而由于回收機(jī)制無(wú)法確定觸發(fā),所以類似的對(duì)象提供了顯示的方式來(lái)釋放外部資源,通常是close()方法。程序建議使用try...finally或者with語(yǔ)句來(lái)顯示關(guān)閉
2 特殊方法
類可以通過定義具有特殊名稱的方法來(lái)實(shí)現(xiàn)由特殊語(yǔ)法調(diào)用的某些操作,這是python的運(yùn)算符重載方法,允許類根據(jù)語(yǔ)言運(yùn)算符定義自己的行為
例如,如果一個(gè)類定義了__getitem__()的方法,并且x是該類的一個(gè)實(shí)例,那么x[i]大致相當(dāng)于type(x).__getitem()__(x, i)
將特殊方法設(shè)置為None,意味著相關(guān)操作不可用;比如,將類的__iter()__方法設(shè)置為None,類將無(wú)法迭代,因此調(diào)用iter()方法時(shí)會(huì)拋出類型錯(cuò)誤(TypeError)的異常
2.1 基本定制
object.__new__(cls[, ...])
創(chuàng)建類的實(shí)例,__new__()是靜態(tài)方法,它將請(qǐng)求實(shí)例的類作為第一個(gè)參數(shù),其余參數(shù)傳遞給對(duì)象構(gòu)造函數(shù),__new__()的返回值應(yīng)該是新的對(duì)象實(shí)例(通常是cls的實(shí)例)
典型的實(shí)現(xiàn)__new__(),是使用適當(dāng)?shù)膮?shù)調(diào)用超類的方法,然后在返回之前根據(jù)需要,修改新創(chuàng)建的類的實(shí)例,super().__new__(cls[, ...])
如果__new__()返回cls的實(shí)例,那么實(shí)例的__init__()方法將被調(diào)用,如__init__(self [, ...]),其中self 代表新實(shí)例,其余的參數(shù)與傳入__new__()方法的參數(shù)相同
如果__new__()沒有返回類的實(shí)例,那么__init__()方法將不會(huì)調(diào)用
__new__()意在允許不可變類型(如數(shù)字、字符 串、元組)的子類自定義實(shí)例的創(chuàng)建;另外,也可以創(chuàng)建自定義的元類(metaclass)來(lái)定制類的創(chuàng)建
object.__init__(self, [...])
在實(shí)例被創(chuàng)建(即__new__())后,尚未返回給調(diào)用者之前調(diào)用,參數(shù)與傳遞給類的構(gòu)造器表達(dá)式一致。如果基類有__init__()方法,子類的__init__()方法,如果存在的話,必須顯示調(diào)用來(lái)保證實(shí)例的基類實(shí)例化操作,如super().__init__([args...])
因?yàn)開_new__()和__init__()共同完成對(duì)象的創(chuàng)建(new用來(lái)創(chuàng)建,init用來(lái)初始化),所以__init__()不允許非空值返回,不然的話會(huì)在運(yùn)行時(shí)拋出類型錯(cuò)誤異常
object.__del__(self)
在實(shí)例將要銷毀時(shí)調(diào)用
object.__repr__(self)
通過repr()內(nèi)置函數(shù)調(diào)用,用來(lái)獲取對(duì)象的機(jī)器表達(dá)式;如果可能的話,這應(yīng)該看起來(lái)像一個(gè)有效的python表達(dá)式,可用于重新創(chuàng)建具有相同值的對(duì)象;如果無(wú)法做到這一點(diǎn),則應(yīng)返回形式上的字符串
object.__str__(self)
通過str(),format(),print()方法調(diào)用,計(jì)算對(duì)象的可打印字符串
與object.__repr__()的不同在于,__str__()不要求返回有效的python表達(dá)式,即可以使用更方便更簡(jiǎn)潔的表示方式
object.__bytes__(self)
通過bytes調(diào)用,計(jì)算對(duì)象的字節(jié)碼
object.__bool__(self)
返回True或False,如果此方法未定義,__len__()被調(diào)用,非0意味著True;如果2個(gè)方法都未定義,則認(rèn)定返回值為True
2.2 基本屬性訪問
object.__getattr__(self, name)
當(dāng)調(diào)用__getattribute__()方法拋出AttributeError異常,或者_(dá)_get__()方法拋出AttributeError異常時(shí),__getattr__()才被調(diào)用,可以返回某個(gè)值,異或同樣拋出異常
object.__getattrbute__(self, name)
訪問實(shí)例的屬性時(shí)無(wú)條件調(diào)用
為了避免無(wú)限遞歸,方法內(nèi)部在訪問對(duì)象的屬性時(shí),應(yīng)始終使用類方法,而不是A.a的形式
object.__setattr__(self, name, value)
屬性賦值時(shí)調(diào)用
object.__delattr__(self, name)
刪除對(duì)象的屬性
object.__get__(self, instance, owner)
在獲取類(owner)的屬性,或者類的實(shí)例(instance)的屬性時(shí)調(diào)用
object.__set__(self, instance, value)
將實(shí)例的屬性設(shè)置為新值
object.__delete__(self, instance)
刪除實(shí)例的屬性
2.3 自定義類創(chuàng)建
object.__init_subclass__(cls)
當(dāng)一個(gè)類繼承自另一個(gè)類時(shí),另一個(gè)類的__init_subclass__()方法都將被調(diào)用
class Philosopher:def __init_subclass__(cls, default_name, **kwargs): super().__init_subclass__(**kwargs) cls.default_name = default_name class AustralianPhilosopher(Philosopher, default_name="Bruce"): pass默認(rèn)情況下,object.__init_subclass__()無(wú)任何操作,但是被調(diào)用時(shí),如果有傳入?yún)?shù),會(huì)拋出異常
元類(metaclass)
默認(rèn)情況下,類對(duì)象通過type()函數(shù)創(chuàng)建,type(name, bases, namespace)
類對(duì)象的創(chuàng)建過程,可以通過傳遞metaclass關(guān)鍵字屬性,或者繼承自另一個(gè)擁有此參數(shù)的類
定義類對(duì)象時(shí),會(huì)執(zhí)行如下操作:
- MRO entries are resolved(還不清楚具體含義)
- 如果基類不是type,會(huì)搜索__mro_entries__方法;如果發(fā)現(xiàn)了,通過original bases tuple調(diào)用;該方法必須返回類的元組,當(dāng)然可以為空
- the appropriate metaclass is determined
- 如果沒有明確指定metaclass,則使用type
- 如果指定了metaclass,且不是type的實(shí)例,那么直接使用
- 如果指定了type的實(shí)例作為metaclass,那么將追溯到頂層的metaclass并使用
- the class namespace is prepared
- 如果metaclass有__prepare__屬性,那么namespace = metaclass.__preprare__(name, bases, **kwargs)
- 如果沒有__prepare__屬性,類的命名空間將被初始化為空的有序映射
- the class body is executed
- the class object is created
- 通過執(zhí)行類主體填充命名空間后,調(diào)用metaclass(name, bases, namespace, **kwargs)方法來(lái)創(chuàng)建類對(duì)象,額外的關(guān)鍵字參數(shù)與__prepare__相同
元類事例
class OrderedClass(type):2.4 模擬可調(diào)用對(duì)象
object.__call__(self [, args...])
使實(shí)例可以像函數(shù)一樣調(diào)用,假設(shè)定義方法x(arg1, arg2, ...),相當(dāng)于調(diào)用x._call_(arg1, arg2, ...)`
2.5 模擬容器類型
object.__len__(self)
len()方法的實(shí)現(xiàn),返回對(duì)象的長(zhǎng)度
object.__getitem__(self, key)
self[key]的實(shí)現(xiàn),對(duì)于序列,key必須為整數(shù)或切片對(duì)象
object.__missing__(self, key)
對(duì)字典類型數(shù)據(jù),調(diào)用self[key]且key不在字典中時(shí)觸發(fā)
object.__setitem__(self, key, value)
對(duì)self[key]賦值,注意只適用于key對(duì)應(yīng)的值可以改變,或者可以追加新key
object.__delitem__(self, key)
刪除self[key]
object.__iter__(self)
當(dāng)容器需要迭代器時(shí),調(diào)用此方法,返回一個(gè)新的迭代器對(duì)象
如果是映射類型,應(yīng)當(dāng)?shù)萜鞯乃墟I
object.__reversed__(self)
reversed()方法的實(shí)現(xiàn),返回一個(gè)新的迭代器,以倒序形式迭代容器中的元素
object.__contain__(self, item)
成員檢測(cè)時(shí)調(diào)用,返回True或False
對(duì)于映射類型,只考慮鍵是否包含,而非值
2.6 with語(yǔ)句
上下文管理器是在執(zhí)行with語(yǔ)句時(shí)定義要建立的運(yùn)行時(shí)上下文的對(duì)象
上下文管理器處理對(duì)代碼執(zhí)行所需的運(yùn)行時(shí)上下文的入口和出口
上下文管理器的典型應(yīng)用包括,保存或恢復(fù)各種全局狀態(tài)、鎖定和解鎖資源、打開關(guān)閉文件等
object.__enter__(self)
與對(duì)象相關(guān)的運(yùn)行時(shí)上下文入口,with語(yǔ)句將方法的返回值綁定到as子句指定的目標(biāo)
object.__exit__(self, exc_type, exc_value, traceback)
與對(duì)象相關(guān)的運(yùn)行時(shí)上下文出口,如果退出時(shí)無(wú)異常,三個(gè)參數(shù)都為None
如果有異常出現(xiàn),此方法希望禁止異常拋出,從而返回一個(gè)真正的值;否則異常將在退出此方法時(shí)正常處理
轉(zhuǎn)載于:https://www.cnblogs.com/aibabel/p/11030976.html
總結(jié)
以上是生活随笔為你收集整理的python 编程模型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 桌面支持--Auto Cad 2012安
- 下一篇: c11语言编译器,GNU C编译器的gn