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