對象是 Python 的抽象數(shù)據(jù)。在一個Python程序中,所有數(shù)據(jù)都通過對象或?qū)ο笾g的關(guān)系表示。(在某種意義上講,和馮·諾依曼的“存儲程序計算機”的模型一致,代碼也是由對象所表示的。)
每一個對象都具有一個標(biāo)識,一個類型和一個值。對象一旦建立,它的表示就永遠(yuǎn)不能改變了;你可以認(rèn)為它是在內(nèi)存中的地址?!?a rel="nofollow" >is’ 運算符用來可以比較兩個對象的身份;‘id’ 可以獲得一個整數(shù)形式的對象標(biāo)示。
CPython 的實現(xiàn)細(xì)節(jié):對于CPython,id(x) 是 x 存儲的內(nèi)存地址。
一個對象的類型決定了這個對象所支持的操作(例如,“有長度嗎?”),并且還定義了針對該類型對象的可能值。type() 函數(shù)返回一個對象的類型(這是一個對象本身)。正如它的身份一樣,一個對象的類型也是不可以改變的。[1]
某些對象的值是可以改變的。那些值可以改變的對象被認(rèn)為是可變的;那些值不可以改變的對象一旦創(chuàng)建就被稱為不可變的。(屬于不可變對象的容器在包括有可變對象的引用時,當(dāng)可變對象改變了時,其實是可變的,但仍被看作是可變對象,因為它所包含的對相機集合不可變的,所以不可變對象和值不可變是不完全一樣的,它更加微妙。)一個對象的可變性是由它的類型來確定的;例如,數(shù)值,字符串和元組是不可變的,而字典和列表是可變的。
對象不用顯式地釋放他們;然而,當(dāng)這些對象變的不能訪問時,它們可能當(dāng)做垃圾被收集。一種處理方式是延遲垃圾收集或者完全忽略 —— 這是回收機制如何實現(xiàn)的質(zhì)量問題,只要求尚能訪問的對象不被回收。
CPython 的實現(xiàn)細(xì)節(jié):CPython 當(dāng)前實現(xiàn)使用一個引用計數(shù)機制和一個可選的循環(huán)垃圾延時檢測機制,只要對象不可用了,就會回收大部分這樣的對象,但不能保證回收中包含有循環(huán)引用。對于循環(huán)回收的詳細(xì)控制情況,見 gc 模塊參考。其他不同的實現(xiàn)方式在 CPython 中可能會改變。 當(dāng)對象變得不能實現(xiàn)時,不要依賴對象可以立馬終結(jié)(所以你需要經(jīng)常明確地關(guān)閉文件)。
注意使用實現(xiàn)的跟蹤和調(diào)試工具時可能會保留本該回收的對象,也要注意使用語句 ‘try...except’ 也可能保留本該回收的對象。
有些對象包含有“外部”資源,像文件或窗口。可以相信在垃圾回收時這些資源也被釋放,但因為垃圾回收不保證一定發(fā)生,這樣的對象提供了顯式的方法釋放這些資源,通常是用 close() 方法。特別推薦使用這種方法釋放包含外部資源的對象。‘try...finally’ 和 ‘with’ 提供了這樣的一個便利途徑。
有些對象包含了其它對象的引用;它們叫做容器。容器的例子有元組,列表和字典。引用作為容器值的一部分。大多數(shù)情況下,當(dāng)我們談及一個容器的值時,我們只是涉及了這個值,而不是所包含的對象;但是,當(dāng)我們談及容器對象的可變性的時候,就只是涉及被直接包含的對象的標(biāo)識了。因此,如果一個不可變對象(如元組)包含了一個可變對象,那么只要這個可變對象的值變了則它的值也就改變了。
類型對對象的大多數(shù)行為都有影響。甚至在某種程度上對對象的標(biāo)識也有重要的影響:對于不可變對象,計算新值的運算符可能實際上返回的是一個已經(jīng)存在的具有相同類型和值的對象的引用,對于可變對象,只是不允許的。例如,在 a=1; b=1 之后,a 和 b 有可能指向一個具有值為1的對象,這依賴于實現(xiàn),但 c=[];d=[] 之后, c 和 d 可以保證是保存了兩個不同的,獨立的,新創(chuàng)建的空列表。(注意 c=d=[] 是把相同的對象賦予了 c 和 d 。)
以下是 Python 內(nèi)建類型的一個列表,擴展模塊( 用C 語言,Java,或者其他語言寫成,取決于實現(xiàn)方式)可以定義其他類型。以后版本的 Python 可能會在這個類型層次中增加其他類型(例如:有理數(shù),高效率存儲的整數(shù)數(shù)組,等等),即使通過標(biāo)準(zhǔn)庫將會提供這些類型。
有些類型描述中包括了一個列出“特殊屬性”的段落。他們提供了一些訪問實現(xiàn)的方法而不是作為一般目的使用。這些定義可能會在未來改變。
無 None
這個類型具有單一值,也只有一個對象有這個值,這個對象可以通過內(nèi)建名字 None 訪問它在許多場合不是無值,例如它在那些沒有返回值的函數(shù)中返回,其值為真值。
未實現(xiàn) NotImplemented
這個類型具有單一值,也只有一個對象有這個值,這個對象可以通過內(nèi)建名字 NotImplemented 訪問。如果數(shù)值方法和許多比較方法的操作數(shù)未提供其實現(xiàn),他們就可能返回這個值。(解釋器會試圖擴展成其它操作,或者其它退化的擦做,它依賴于運算符)他的真值為真。
更多細(xì)節(jié)見 Implementing the arithmetic operations 。
省略 Ellipsis
這個類型具有單一只,也只有一個對象有這個值。這個對象可以通過文字 ... 或者內(nèi)建名字 Ellipsis 訪問。其真值為真。
數(shù)值型 nubmbers.Numbers
它們由數(shù)值型字面值生成,或由算術(shù)運算和內(nèi)置算術(shù)函數(shù)作為值返回。數(shù)值型對象是不可變的;一旦創(chuàng)建其值就不可以改變。Python 的數(shù)值型和數(shù)學(xué)上的關(guān)系非常密切,但要受到計算機的數(shù)值表達能力的限制。
Python 對整數(shù),浮點數(shù)和復(fù)數(shù)區(qū)別對待:
numbers.Integral
描述了數(shù)學(xué)上的整數(shù)集(正數(shù)和負(fù)數(shù))。
有2種整數(shù)類型:
數(shù)值型整數(shù) Integers (int)
數(shù)值型整數(shù)的表示范圍在語言上是無限制的,只受限于你的內(nèi)存(虛擬內(nèi)存)。對于以移位和屏蔽為目的的運算,數(shù)值型正數(shù)被認(rèn)為是二進制的形式,如果是負(fù)數(shù),那么就被轉(zhuǎn)換成二進制補碼形式,符號位向左擴展。
布爾型整數(shù) Booleans (bool)
布爾型整數(shù)的真值是用假和真來表示的。對于布爾型對象的值只能通過假和真表示。布爾類型是整數(shù)類型的子類型,分別用數(shù)值 0 和 1 來表示,但是當(dāng)返回值的類型是字符時,其分別用 "False" 或者 "True" 表示。
整數(shù)表示法的這個規(guī)則是為了使對負(fù)數(shù)操作時盡量有實際意義。
浮點數(shù) numbers.Real (float)
本類型表示了機器級的雙精度浮點數(shù)。是機器的體系結(jié)構(gòu)和C實現(xiàn)的浮點數(shù)范圍和控制溢出方法屏蔽你不需知道的細(xì)節(jié)。Python 不支持單精度浮點數(shù),使用它的原因通常是減少CPU負(fù)荷和節(jié)省內(nèi)存,但是這一節(jié)省被對象在Python中的使用開銷所抵消,因此沒有必要支持兩種浮點數(shù)使語言變的復(fù)雜。
復(fù)數(shù) numbers.Complex (complex)
本類型描述了一對機器級的雙精度浮點數(shù),在浮點數(shù)中的警告內(nèi)容也適用于復(fù)數(shù)類型。復(fù)數(shù) z 的實部和虛部可以通過屬性 z.real 和 z.imag 獲得。
有序類型 Sequences
本類型描述了用非負(fù)數(shù)索引的有限的有序集合。內(nèi)建函數(shù) len() 返回有序類型數(shù)據(jù)中的項數(shù)當(dāng)有序類型數(shù)據(jù)的長為 n 時,索引號為 0,1,...,n-1。有序類型數(shù)據(jù) a 中的項 i ,可以以 a[i] 表示。
有序類型也支持片斷:a[i:j] 可以表示滿足 i <= k < j 的所有項 a[k]。在使用這個表達式時,它具有相同的有序類型,這也隱含著索引重新從0開始計。
有些有序類型用第三個“步驟”參數(shù)來支持“擴展片斷”:a[i:j:k] 選擇所有項的索引 x,其中 x = i + n * k,n >= 0 并且 i <= x < j。
有序類型按照可變性分為兩類:
不可變類型 Immutable sequences
一個不可變對象一旦建立其值不可能再改變。(如果這個對象包括其它對象的引用,這個被引用的對象可以是可變對象并且其值可以變化;但為該不可變對象所直接引用的對象集合是不能變的。)
以下類型是不可變類型:
字符串 Strings
字符串的序列值體現(xiàn)了 Unicode 的代碼點,字符串中所有代碼點的范圍是 U+0000 - U+10FFF。Python 不支持 char 類型,相反,每個代碼的字符串用長度1表示一個字符串對象。內(nèi)建函數(shù) ord() 從字符串轉(zhuǎn)換為代碼點形成一個整數(shù)的范圍 0 - 10FFFF,chr() 將一個范圍在 0 - 10FFFF 的整數(shù)對應(yīng)長度1的字符串對象。str.encode() 可以使用給定的明文編碼將 str 轉(zhuǎn)換成 bytes, 并且 bytes.decode() 可以實現(xiàn)相反轉(zhuǎn)換。
元組 Tuples
元組對象的項可以是做任意的 Python 對象。具有兩個或多個項的元組是用逗號分隔開表達式列表,只有一項的列表(獨元)其項可以后綴一個逗號使其成為滿足要求元組要求的表達式(一個表達式本身不能創(chuàng)建一個元組,因為圓括號本身用于表達式的分組)。一個空元組可以以一對空圓括號表示。
字節(jié) Bytes
字節(jié)對象是不可變的數(shù)組,每個項由8位字節(jié)組成,由整數(shù)范圍為 0 <= x < 256 表示。字節(jié)文字(如 b'abc')和內(nèi)建函數(shù) bytes() 可以被用來構(gòu)建字節(jié)對象。同時,字節(jié)對象可以經(jīng)由 decode() 方法被解碼為字符串。
可變對象 Mutable sequences
可變對象可以在其創(chuàng)建后改變,其下標(biāo)表示和片斷表示可以作為賦值語句和 del (刪除)語句的對象。
目前只有一種可變類型。
列表 Lists
列表對象的項可以是任意類型的 Python 對象。列表對象是在方括號之間的用逗號分開的表達式表。(注意,形成長度為0或者1的鏈表不要求特別的寫法)。
字節(jié)數(shù)組 Byte Arrays
字節(jié)數(shù)組對象是一個可變的數(shù)組,它們是由內(nèi)建函數(shù) bytearray() 構(gòu)造創(chuàng)建。除了是可變的(和無序的),字節(jié)數(shù)組以其他方式提供相同的界面和功能不變的字節(jié)對象。
擴展模塊 array 提供一個額外的可變序列類型模板, collections 模塊。
集類型 Set types
集類型對象具有無序性,有限集的獨一無二性,和不變性。因此,它們不能被任何下標(biāo)所搜引,然而,它們可以進行遍歷,并有內(nèi)建函數(shù) len() 返回遍歷數(shù)。集的常見應(yīng)用包括快速加入測試,刪除重復(fù)虛了,和計算數(shù)學(xué)操作,如十字路口,并,差異和對稱查分。
對于集元素,相同的不變性屬性作為申請字典關(guān)鍵字。注意,數(shù)字類型遵從數(shù)字比較的正常規(guī)則:如果兩個數(shù)字比較后相等(比如1和1.0),那么會只有一個數(shù)字包含在集合里。
目前有兩種原始集類型:
集 Sets
這種代表可變的集合,它們是由內(nèi)建函數(shù) set() 構(gòu)建,并且之后可變用多發(fā)方法去修改的,比如 add()。
凍結(jié)集 Frozen sets
這種代表不可變的集合,它們是由內(nèi)建函數(shù) frozenset() 構(gòu)建,由于凍結(jié)集的不可變性以及無序性 hashable ,它也可以用來作另外一個集合的元素或者字典的關(guān)鍵字。
映射類型 Mappings
本類型描述了可以是由任意類型作索引的有限對象集合。下標(biāo)表示法 a[k] 從映射類型對象中選擇一個由 k 索引項,它們可以用作賦值語句和 del 語句的目標(biāo)。內(nèi)建函數(shù) len() 返回映射對象的項的個數(shù)。
當(dāng)前只有一個內(nèi)置的映射類型:
字典 Dictionaries
本類型表達了幾乎是任意類型對象都可作索引的有限對象集合。不可接受的鍵值僅僅是那些包括有列表和字典的值,或那些是通過值比較而不是通過對象標(biāo)識符比較的類型的值。其原因是字典的高效實現(xiàn)要求鍵的哈希值保持不變。用于鍵值的數(shù)值型在比較時使用通常的規(guī)則:如果兩值相等(如:1和0),那么它們可以互換地索引相同的字典項。
字典是可變的,它們由 ... 語法創(chuàng)建(詳見 Dictionary displays )。
擴展模塊 dbm.ndbm 和 dbm.gnu 提供了另外的映射類型的例子, 同 collections 模塊。
可調(diào)用類型 Callable types
這是一個可用的函數(shù)調(diào)用操作類型(詳見 Calls),應(yīng)用于:
用戶自定義函數(shù) User-defined functions
一個自定義函數(shù)對象由函數(shù)定義(詳見 Function definitions)。創(chuàng)建在函數(shù)調(diào)用時應(yīng)該與定義時的形式參數(shù)相同數(shù)目參數(shù)。
特殊屬性:
| 屬性 | 意義 | - |
|---|---|---|
__doc__ |
是函數(shù)的文檔串,如果無效就是 None,不可以被子類繼承 |
可寫 |
__name__ |
是函數(shù)名稱 | 可寫 |
__qualname__ |
是函數(shù)的限定名稱,在版本 3.3. 中的新屬性 | 可寫 |
__module__ |
定義在函數(shù)模塊里的定義,如果無效就是 None |
可寫 |
__defaults__ |
一個元組包含默認(rèn)參數(shù)值,這些參數(shù)是默認(rèn)的,如果沒有默認(rèn)參數(shù)值就是 None, |
可寫 |
__code__ |
一個編譯后的代碼對象, | 可寫 |
__globals__ |
是一個引用,指向保存了函數(shù)的全局變量的字典——如果在函數(shù)所在模塊中定義了全局變量的話, | 只讀 |
__dict__ |
包含了支持任意函數(shù)屬性的命名空間, | 可寫 |
__closure__ |
要么是 None,要么是包括有函數(shù)自由變量綁定的單元的元組, |
只讀 |
__annotations__ |
是一個包含注釋的字典參數(shù),字典的關(guān)鍵字是參數(shù)名字,并且如果有提供的話,返回注釋 return, |
可寫 |
__kewdefaults__ |
是一個只包含默認(rèn)關(guān)鍵字的字典, | 可寫 |
大部分的“可寫”屬性需要檢查分配的值的類型。
函數(shù)對象也支持獲取和設(shè)置任意屬性,它可以被使用,例如,元數(shù)據(jù)功能。常規(guī)屬性一樣用于獲取和設(shè)置這些屬性。注意,當(dāng)前的實現(xiàn)只支持函數(shù)屬性對用戶定義的函數(shù),功能屬性內(nèi)置函數(shù)可能在未來才會支持。
關(guān)于函數(shù)的定義可以由它的代碼對象得到;見下面關(guān)于內(nèi)部對象的描述。
實例方法 Instance methods
實例方法合并了一個類,一個類實例和任何可調(diào)用對象(一般是用戶自定義函數(shù))。
特殊的只讀屬性: __self__ 是類實例對象,__func__ 是函數(shù)對象; __doc__ 是其方法的文檔(同 __func__.__doc__); __name__ 是方法名(同 __func__.__name__); __modele__ 是定義方法的模塊名,如果無效則為無 None。
方法也支持訪問(不是設(shè)置)的其實際所調(diào)用的函數(shù)的任意屬性。
如果類的屬性是一個用戶定義函數(shù)對象或類方法對象,那么獲得類屬性的用戶可以創(chuàng)建自定義方法對象(也可能通過這個類的一個屬性)。
當(dāng)用戶自定義方法對象采用一個用戶自定義函數(shù)對象來創(chuàng)建時,這個對象來自于它的一個實例類,它的 __self__ 屬性是個實例,并且該方法稱為是捆綁的。新方法的 __func__ 屬性是原始函數(shù)對象。
當(dāng)用戶自定義方法對象采用另外一個類或?qū)嵗姆椒▽ο髣?chuàng)建時,其特性與函數(shù)對象創(chuàng)建時相同的,不同之處是這個 __func__ 新類的屬性不是原始函數(shù)對象,而是它的 __func__ 屬性。
當(dāng)調(diào)用實例方法對象時,實際調(diào)用的是函數(shù)( __func__ ),同時在參數(shù)列表前插入類實例(__self__ )。比如:當(dāng)類 C 包含了一個函數(shù)定義 f(),并且 x 是 C 的一個實例,調(diào)用 x.f(1) 相當(dāng)于調(diào)用 C.f(x,1)。
當(dāng)一個實例方法對象時由一個類方法對象衍生而來時,存儲在 __self__ 的“類實例”實質(zhì)上將會是類本身,所以不論調(diào)用 x.f(1) 或者 C.f(1) 相當(dāng)于調(diào)用 f(C,1), 其中 f 是實際函數(shù)。
注意,由函數(shù)對象轉(zhuǎn)變到實例方法對象,每次都會檢索實例中的屬性。在某些情況下,卓有優(yōu)化是成效的優(yōu)化是將屬性分配給一個局部變量并調(diào)用它。同時應(yīng)注意,這種轉(zhuǎn)變只會發(fā)生在在用戶自定義函數(shù)上,檢索其他的可調(diào)用對象(以及不可調(diào)用對象)不需要這種轉(zhuǎn)變。同樣重要的是要注意,具有類實例屬性的用戶自定義函數(shù)不能轉(zhuǎn)換成綁定方法;當(dāng)且僅當(dāng)發(fā)生在函數(shù)是一個類的屬性時。
生成器函數(shù) Generator functions
一個使用 yield 的語句(見 yield 語句 )的方法或函數(shù),它叫做生成器函數(shù)。這樣的函數(shù),在返回后,通常返回一個迭代子對象,一個可以用于執(zhí)行函數(shù)的對象。調(diào)用對象的 iterator.next() 方法會引起函數(shù)的執(zhí)行,直到其使用 yield 語句返回一個值。當(dāng)函數(shù)在執(zhí)行到 return 語句時,或在末尾結(jié)束時,會拋出異常 StopIteration,此時迭代器也到達了返回值集合的結(jié)尾。
內(nèi)建函數(shù) Built-in functions
一個內(nèi)建函數(shù)就是一個 C 函數(shù)的包裝,例如內(nèi)建函數(shù) len() 和 math.sin() (math 是標(biāo)準(zhǔn)的內(nèi)建模塊)。參數(shù)的類型和數(shù)目都由C函數(shù)檢測,特殊的只讀屬性:__doc__ 是函數(shù)的文檔串, 或者無效為無 None; __name__ 是函數(shù)名;__self__ 設(shè)為 None(見下述); __module__ 是模塊名,或者無效為無 None。
內(nèi)建方法 Built-in methods
這實際上是內(nèi)建函數(shù)的一個不同的包裝而已,此時傳遞給C函數(shù)一個對象作為隱含的參數(shù)。例如,內(nèi)建方法 alist.append() 假定 alist 是一個列表對象,此時特殊只讀屬性 __self__ 指定為對象 alist。
類 Classes
類是可調(diào)用的。這些對象通常是自己的新實例的工廠,但是變化可能是重寫 __new__ () 類對象。傳送調(diào)用的參數(shù)到 __new__ (), 而且典型情況是傳送到 __init__ () 來初始化成新實例。
類實例 Class Instances
任意類實例可以通過定義一個 __call__ () 方法類去調(diào)用。
模塊 Modules
模塊是 Python 代碼的基本組成單元,并由導(dǎo)入系統(tǒng) import system 創(chuàng)建,可以通過 import 語句或者諸如函數(shù) importlib.import_module() 和內(nèi)建函數(shù) __import__ ()。一個模塊有一個名字空間,用字典對象實現(xiàn)(在模塊定義中的函數(shù)可以通過 __globals__ 屬性來訪問這個字典)。把對屬性的訪問翻譯成查找這個字典。例如,m.x 等價于 m.__ dict__["x"]。模塊對象并不包含用來初始化該模塊的代碼對象(因為一旦初始化完成它就不再需要了)。
屬性的賦值更新模塊的空間名字,例如,m.x = 1 等價于 m.__dict__ ["x"]`。
特殊只讀屬性:__dict__ 是字典形式的模塊名字空間。
Python 實現(xiàn)細(xì)節(jié):由于 CPython 清理模塊字典的方式,當(dāng)模塊超出范圍時,即使字典還在引用,字典模塊也將被消除。為避免這種情況發(fā)生,在直接使用字典時應(yīng)該備份字典或?qū)⑵浔A粼谀K附近。
預(yù)定義的可寫屬性: __name__ 是模塊名;__doc__ 是模塊的文檔串,如果無效即為 None;__file__ 是被裝載模塊的文件路徑名, 因為C模塊不提供些屬性,該模塊已連接至解釋器中,對于那些從共享庫裝載的模塊,這個屬性是那些共享庫的路徑。
自定義類 Custom classes
自定義類類型由類定義創(chuàng)建(見類定義 Class definitions)。一個類有一個用字典對象實現(xiàn)的名字空間,類屬性的訪問可以轉(zhuǎn)換成對該字典的查找,例如,C.x 被解釋成 C.__dict__ ["x"]`(雖然有許多允許定位屬性的掛鉤)。當(dāng)屬性名未找到時,查找是深度優(yōu)先的。這種基本類搜索使用 C3 方法解析正確行為,即使在‘鉆石’繼承結(jié)構(gòu)那里有多重繼承回到共同祖先的路徑。更多細(xì)節(jié)在 Python 中使用的 C3 MRO,參考隨著 2.3發(fā)布的文檔里 https://www.python.org/download/releases/2.3/mro/。
當(dāng)一個類屬性引用(對于類 C 說)應(yīng)該讓步于一個類方法對象時,它會變成一個實例方法對象,其屬性__self__ 是 C。當(dāng)它應(yīng)該讓步于一個靜態(tài)方法對象時,它會變成靜態(tài)方法對象的封裝對象。見另一種方式的實現(xiàn)描述 Implementing Descriptors ,從一個類檢索屬性可能不同于那些實際包含在其字典__dict__。
類屬性的賦值會更新類的字典,而不是基類的字典。
一個類對象可以創(chuàng)建(見上),這樣會產(chǎn)生一個類實例(下述)。
特殊屬性: __name__ 是類名;__module__ 是類所定義的模塊名;__dict__ 是包括類名字空間的字典; __bases__ 是一個元組(可能是空或獨元),包括其基類,以基類列表中他們的排列次序出現(xiàn); __doc__ 是類的文檔串,如果無效,它就是無 None。
類實例 Class instances
類實例可以通過調(diào)用一個類對象來創(chuàng)建,類實例可以有一個用字典實現(xiàn)的名字空間,它只由搜索屬性范圍的第一個結(jié)果構(gòu)成。如果屬性沒在那找到,并且實例的類有那個名字的屬性,就繼續(xù)在類屬性中尋找。如果找到的是一個用戶自定義函數(shù)對象(而不是其它情況),它被轉(zhuǎn)換成一個實例方法對象,它的` self屬性是個實例。 靜態(tài)方法和類方法對象也可以轉(zhuǎn)換,見前文在 “Classes” 中所述。另一種方式,通過實例檢索類的屬性可能不同于對象實際存儲在類__ dict中的,見 *[Implementing Descriptors](https://docs.python.org/3/reference/datamodel.html#descriptors)* 部分。如果沒有類屬性找到,并且對象的類有方法 [getattr`](https://docs.python.org/3/reference/datamodel.html#object.getattr__) (),那就調(diào)用它來滿足查找請求。
屬性賦值和刪除會更新實例目錄,而不是類的字典,如果類具有方法 __setattr__ () 和 __delattr__ (),則它們會在更新類實例屬性時調(diào)用,而不是實例字典直接更新。
類實例可以偽裝成數(shù)字,序列,或者具有方法映射成某些特別的名字。 見 Special method names 部分。
特殊屬性: __dict__ 是字典屬性;__class__ 是實例屬性。
輸入/輸出對象(或稱文件對象) I/O objects
一個文件對象 file object 描述了一個開放的文件。 有多種可用的快捷方式來創(chuàng)建文件對象: 內(nèi)建函數(shù) open(),以及 os.open(),os.fdopen(),和套接字對象方法 makefile() (或許也可以通過其他擴展模塊的函數(shù)或方法)。
對象 sys.stdin,sys.stdout,和 sts.stderr 被相應(yīng)的初始化成解釋器的標(biāo)準(zhǔn)輸入流,標(biāo)準(zhǔn)輸出流,和標(biāo)準(zhǔn)錯誤輸出流;它們都是開放文本模式,因此遵循抽象類 io.TextIOBase 定義的接口。
內(nèi)部類型 Internal types
少部分由解釋器內(nèi)部使用的類型,開放給了用戶。它們的定義可能會在未來的解釋器版本中改變,但都會在這兒提及。
代碼對象 Code objects
代碼對象表達了字節(jié)編譯過的可執(zhí)行 Python 代碼,或者叫字節(jié)碼。代碼對象和函數(shù)對象的不同在于函數(shù)對象包括了一個外在的全局變量引用(其所定義的模塊),而代碼對象不包括上下文。默認(rèn)參數(shù)值存入函數(shù)對象中,而代碼對象則不(因為它們的值由運行時計算)。不像函數(shù)對象,代碼是不可改變的,并且不包括對可變對象的引用。
特殊屬性: co name 給出了函數(shù)名;co argument 是位置參數(shù)的數(shù)目(包括有默認(rèn)值的參數(shù));co nlocals 是函數(shù)中局部變量的數(shù)目。co varnames 是一個包括局部變量名的元組(從參數(shù)名開始);co callvars 是一個元組,包括由嵌套函數(shù)所引用局部變量名;co freevals 包括了既不是局部變量也不是全局變量的;co code 包括了編譯過的字節(jié)碼指令序列的字符串;co consts 包括字節(jié)碼中使用的字面值的元組;co names 包括字節(jié)碼中使用的名字的元組;co filename 包括著編譯過的字節(jié)碼文件名;co firstlineno 是函數(shù)首行行號;co lnotab 是一個字符串,是字節(jié)碼偏移到行號的映射(詳見解釋器代碼);co stacksize 是所需要的堆棧尺寸(包括局部變量);co flags 是一個整數(shù),其解釋成為許多解釋器的標(biāo)志。
以下標(biāo)志位由 co _ flags 定義:如果函數(shù)使用 *argument 語法來接受任意數(shù)目的位置參數(shù),就置位 0x04;如果函數(shù)使用 *keywords 語法來接受任意數(shù)量的關(guān)鍵字參數(shù),就置位 0x08;如果函數(shù)是個生成器,就置位 0x20。
未來功能還聲明(from __future__ import division)在 co _ flages 中使用位表明編譯代碼對象是否啟用了一個特定的嵌入式功能:如果編譯函數(shù)啟用了嵌入式功能,則置位 0x2000;而在老版的 Python 中使用位 0x10 和 0x1000。
在 co _ flages 中的其他為預(yù)留為內(nèi)部使用。
如果一個代碼對象描述一個函數(shù),則 co _ consts 的第一項是該函數(shù)的文檔串,如果未定義,它就是無 None。
堆棧結(jié)構(gòu)對象 Frame objects
堆棧結(jié)構(gòu)對象描述了可執(zhí)行結(jié)構(gòu),它們會在跟蹤回溯對象中出現(xiàn)(下述)。
特殊只讀屬性:f back 指出前一個堆棧結(jié)構(gòu)(向著調(diào)用者的方向),如果位于堆棧的底部它就是 None;f code 指出本結(jié)構(gòu)中能執(zhí)行的代碼對象。f locals 是用于查找局部變量的字典;f globals 用于全局變量;f builtin 用于內(nèi)建名字;f lasti 給出精確的指令(是一個代碼對象的字符串的索引)。
特殊可寫屬性:f trace 如果非空,就是從每個源代碼行的開始處調(diào)用的函數(shù)(用于調(diào)試器);f lineno 給出行號——寫這個函數(shù)從內(nèi)部跟蹤的行(只限于最底層堆棧)。調(diào)試器可以通過編寫 f _ lineno 實現(xiàn)跳轉(zhuǎn)命令(即設(shè)置下一條語句)。
堆棧結(jié)構(gòu)對象支持一種方法:
堆棧結(jié)構(gòu)清除 frame.clear()
這種方法清除所有局部變量的引用。同時,這個結(jié)構(gòu)堆棧屬于一個發(fā)生器,那么會終結(jié)這個發(fā)生器。這有助有終止堆棧結(jié)構(gòu)對象循環(huán)(比如,供以后使用異常捕獲和回溯存儲)。
如果當(dāng)前結(jié)構(gòu)正在執(zhí)行,上報 RuntimeError。
新版本3.4。
跟蹤回溯對象 Traceback objects
跟蹤回溯對象描述一個異常的?;厮?,跟蹤回溯對象在異常發(fā)生時創(chuàng)建,在展開可執(zhí)行堆棧搜索異常處理器時,每個展開層的跟蹤回溯對象插進當(dāng)前跟蹤回溯對象的前面。在遇到異常處理器時,跟蹤回溯對象也對程序有效了。(見 try 語句) 它可以由 sys.exc _ info() 返回的元組的第三項訪問到。后一種是推薦的接口,因為它也可以使用多線程的程序中工作良好。當(dāng)程序中未包括適當(dāng)?shù)漠惓L幚砥? 跟蹤回溯對象就被打印到標(biāo)準(zhǔn)錯誤輸出流上。如果工作在交互方式上,它也可以通過 sys.last _ traceback。
特殊只讀屬性:tb text 是堆棧的下一層(向著異常發(fā)生的那一層結(jié)構(gòu)),或者如果沒有下一層,就為 None。 tb frame 指出當(dāng)前層次的可執(zhí)行結(jié)構(gòu);tb lineno 給出異常發(fā)生的行號;tb lasti 指出精確的指令;如果異常發(fā)生在沒有 except 或 finally 子句匹配的 try 語句中的話,這里的行號和指令可能與結(jié)構(gòu)中的行號和指令不同。
片斷對象 Slice objects
片斷對象用片段方法 __getitem()__ 來描述。他們也是通過內(nèi)建函數(shù) slice() 來創(chuàng)建。
特殊只讀屬性:start 是下界,step 是上界,step 是步進值,如果在片段中忽略了它,就是 None。這些屬性可以是任意類型的。
片斷對象支持一種方法:
片斷索引 slice.indices(self, length)
這個方法接受一個整數(shù)參數(shù) length 并計算片斷信息,切片對象用于描述 length 項序列。它返回一個元組包含為三個整數(shù),分別代表開始索引,停止索引啟動和偏度的步進或步長,處理缺失或界外指數(shù)的方式與普通片斷一致。處理缺失或界外索引的方式與普通片斷一致。
靜態(tài)方法對象 Static method objects
靜態(tài)方法對象提供一種戰(zhàn)勝上述轉(zhuǎn)換函數(shù)對象方法。靜態(tài)方法對象包裝在其他對象周圍,通常是一個用戶定義的方法對象。當(dāng)一個靜態(tài)方法對象從一個類或一個類實例檢索時,返回的對象實際上是包裝對象,它不受任何進一步的轉(zhuǎn)換。它本身并不是調(diào)用靜態(tài)方法對象,盡管他們通常包裝對象,但并不能自我調(diào)用。靜態(tài)方法創(chuàng)建的對象是內(nèi)建函數(shù) staticmethod() 構(gòu)造。
類方法對象 Class method objects
類方法的對象是一個在其他對象周圍的包裝器,就像一個靜態(tài)方法對象,它改變從類和類實例中檢索的方式。上述的這種類方法對象的方式在“用戶自定義方法”中有體現(xiàn)。 用內(nèi)建函數(shù) classmethod() 構(gòu)建器來創(chuàng)建類方法對象。
一個類可以實現(xiàn)以特殊句法才調(diào)用的某些操作(例如算術(shù)運算,下標(biāo)操作及片斷操作),這是通過以特殊名字定義方法來實現(xiàn)的。這是 Python 的操作符重載方法,允許類來定義自己的行為對語言操作符。例如,如果一個類定義了的方法名為 __getitem__ (),并且 x 是這個類的實例,那么 x[i] 就等價于 type(x).__ getitem__(x,i)。除了所提及的地方,試圖執(zhí)行沒有適當(dāng)?shù)姆椒ǘx的操作會引起一個異常的拋出(典型的 AttributeError 和 TypeError)。
當(dāng)實現(xiàn)一個模擬任何內(nèi)建類型的類時,重要的地方在于模擬的程度只要使對象模擬時有效就行了。例如,某些有序類型的對象可能在單獨提取某引起值時有效,但在使用片斷時是沒有意義的。(這樣的一個例子是在W3C的文檔對象模型中的NodeList接口。)
object.` new(cls[,...]) 在實例創(chuàng)建調(diào)用時,__ new是一個靜態(tài)方法(特殊情況下不需要聲明),它要求類的實例作為第一個參數(shù)。剩余的參數(shù)傳遞到對象構(gòu)造表達式(調(diào)用到類),new__` 返回值應(yīng)該是一個新的對象實例(通常是 cls 的實例)。
典型的實現(xiàn)方式是創(chuàng)建一個類的新實例,通過使用具有適當(dāng)參數(shù)的 super(currentclass,cls).` new(cls[, ...]) 調(diào)用超級類的__ new__` ,然后根據(jù)需要,在返回之前修改新創(chuàng)建的實例。
如果` new返回一個 cls 實例,那么新實例的方法__ init` () 將會像 ``init(self[,...])被調(diào)用, 這時候,新實例和剩余的參數(shù)被傳遞給new__ () 相同。
如果` new不返回一個 cls 實例,那么就不會調(diào)用這個新實例的__ init__` ()。
__new__ 的主要目的是允許子類不可變類型(如整數(shù),字符或元組)定制實例創(chuàng)建。也通常覆蓋在自定義原類中來創(chuàng)建自定義類。
object.` init(self[, ...]) 實例在創(chuàng)建(通過new創(chuàng)建)之后才會被調(diào)用,但之前返回給調(diào)用者。構(gòu)造函數(shù)的參數(shù)是指傳遞表達式。如果一個基本類具有方法__ init` ()或派生類的方法 init__ (),必須顯式的調(diào)用它,以確保實例部分的基本類初始化;比如: BaseClass.__ init__( self, [args...])。
因為` new和__ init` 同時作用來構(gòu)建對象 (new__ 創(chuàng)建它,` init來定制),沒有 non-'None' 值可能通過__ init__` 來返回,這樣做會導(dǎo)致在運行時上報 Typeerror 。
object.` del` (self)
在實例被刪掉時被調(diào)用,也叫作析構(gòu)器。 如果其基類也具有 del() 方法,繼承類應(yīng)該在其 del() 顯式地調(diào)用它,以保證適當(dāng)?shù)貏h掉它的父類部分。注意,在 del() 通過創(chuàng)建新的引用來推遲刪除操作是允許的,但這不是推薦的做法。它然后在最后這個引用刪除時被調(diào)用。不能保證在解釋器退出時,仍存在的對象一定會調(diào)用 del() 方法。
注意: del x 不直接調(diào)用 x.del() —— 前者將引用計數(shù)減一,而后者僅僅在引用計數(shù)減到零時才被調(diào)用。有一些經(jīng)常使用的方法。 可以防止引用計數(shù)減為零:對象之間的循環(huán)引用(例如,一個雙鏈表或一個具有父結(jié)點和子結(jié)點指針的樹形數(shù)據(jù)結(jié)構(gòu));對某函數(shù)堆棧結(jié)構(gòu)上的引發(fā)異常的對象進行引用(跟蹤回溯對象保存在 sys.exc_info()[2] 是以保持其有效);或者在交互模式下對某函數(shù)堆棧上的引發(fā)了沒有處理器的異常的對象做引用(跟蹤回溯對象保存在 sys.last_traceback 中以保持其有效)。第一種方法僅能通過顯式地破壞循環(huán)才能恢復(fù),后兩種情況,可以通過將 sys.last_traceback 賦給None來恢復(fù)。僅當(dāng)循環(huán)引用檢測器選項被允許時(這是默認(rèn)的)循環(huán)引用才能為垃圾回收機制所發(fā)覺, 但這只在沒有相關(guān)的 Python 級的 del_() 方法時才會被清除。關(guān)于 del_() 方法怎樣處理循環(huán)引用的進一步信息參見 gc 模塊,該處具體地描述了垃圾回收。
告警:因為調(diào)用 del_() 方法的不確定性,在它執(zhí)行時的異常會被忽略,而只是在 sys.stderr 打印警告信息。另外,當(dāng)某模塊被刪除,相應(yīng)的 del_() 方法調(diào)用時(例如,程序退出時),有些為 del_() 方法所引用的全局名字可能已經(jīng)刪除了。由于這個原因, del_() 方法應(yīng)該對其外部要求保持到最小。 Python1.5 可以保證以單下劃線開始的全局名字在其它全局名字被刪除之前從該模塊中被刪除;如果沒有其它對存在的全局名字的引用,這會對確定那些已導(dǎo)入的模塊在調(diào)用 del_() 之后有那些還是有效
的時是有所幫助的。
object.` repr(self) 由 [repr()](https://docs.python.org/3/library/functions.html#repr) 內(nèi)建函數(shù)調(diào)用或者在串轉(zhuǎn)換(保留引號)時用來計算對象的“正式說明”字符串,盡可能的,這應(yīng)該是一個能以相同的值重建一個對象的有效的 Python 表達式(在給定的適當(dāng)有環(huán)境下),如果這不 可能的,也應(yīng)該是返回一個“...某些有用的信息...”形式的字符串。 返回值必須是一個字符串。如果類定義 [repr()](https://docs.python.org/3/library/functions.html#repr) 而不是 [str` ()](https://docs.python.org/3/reference/datamodel.html#object.__str__), 那么當(dāng)一個“非正式”字符串表示的類的實例是必須的時候, repr() 也會被使用。
本函數(shù)典型地用法是用于調(diào)試,所以這個串表述成詳盡并無歧義是十分重要的。
object.` str` (self)
由 str(object) 內(nèi)建函數(shù)調(diào)用,或由 format() 和 print() 語句來計算該對象的“非正式”串描述。返回值必然是個字符串 string 對象。
這與 object.` repr` () 是不同的,因為它不 要求必須為一個有效的 Python 表達式:可以采用一個更通俗或更簡潔的表述方式。
這種典型的實現(xiàn)方法可以通過內(nèi)建類型 object 調(diào)用 object.` repr` () 來定義。
object.` bytes(self) 由 [format()](https://docs.python.org/3/library/functions.html#format) 內(nèi)建函數(shù)(和擴展,類 [str](https://docs.python.org/3/library/stdtypes.html#str) 的 [strformat()](https://docs.python.org/3/library/stdtypes.html#str.format) 方法)調(diào)用,它產(chǎn)生一個“格式化”對象的字符串表示。format_spec參數(shù)是一個包含了要求格式化選項描述的字符串。format_spec參數(shù)的解釋是實現(xiàn) [format` ()](https://docs.python.org/3/reference/datamodel.html#object.__format__),然而大多數(shù)類代表格式化內(nèi)置的類型之一,或者使用類似的格式化的語法。
詳見 Format Specification Mini-Language 標(biāo)準(zhǔn)格式化特征的描述。
它的返回值必須是一個字符串對象。
在版本3.4中的改變:如果傳遞一個空的字符串,對象本身的` format` 方法會提出類型錯誤 TypeError。
object.` lt(self,other) object.__ le` (self,other)
object.eq__ (self,other)
object.` ne(self,other) object.__ gt` (self,other)
object.ge__ (self,other)
它們稱為“厚比較”方法集, 具體的方法名和相應(yīng)的運算符的對應(yīng)關(guān)系如下: x<y 調(diào)用 x.__ lt(y),x<=y 調(diào)用 ``le(y),x==y 調(diào)用 ``eq(y),x!=y 調(diào)用 ``ne(y),x>y 調(diào)用 ``gt(y),x>=y 調(diào)用 ``ge__(y)。
如果它對給定的參數(shù)對沒有實現(xiàn)操作, 一個厚比較方法可以返回 NotImplemented。按照慣例,一個成功的比較會返回 False和 True。不論如何,這些方法可以返回任何值,因此如果比較操作在布爾型文本中使用(如,if 條件語句),Python 將在值上調(diào)用 bool() 來決定結(jié)果是真還是假。
有隱含的比較運算符之間的關(guān)系。 x==y 為真相并不意味著 x!=y 為假。相應(yīng)的,當(dāng)定義 __eq__ () 時,同時也應(yīng)該定義 __ne__ (),比便于達到預(yù)期的操作。見支持自定義比較和可作為字典關(guān)鍵字使用的創(chuàng)建 hashable 的 __hash__ ()。
對于這些方法是沒有互換參數(shù))版本的(在左邊參數(shù)不支持該操作, 但右面的參數(shù)支持時使用)。雖然, `_lt _() 和 __gt__ (),__le__ () 和 __ge__(), __eq__ ()和 __ne__ () 看起來是反函數(shù)。
厚比較方法的參數(shù)并不是非要有。
從一個根操作自動生成命令的操作,見 functools.total_ordering()。
object.` hash(self) 由內(nèi)建函數(shù) [hansh()](https://docs.python.org/3/library/functions.html#hash) 調(diào)用,用于操作散列的集合,包括 [set](https://docs.python.org/3/library/stdtypes.html#set),[frozenset](https://docs.python.org/3/library/stdtypes.html#frozenset),以及 [dict](https://docs.python.org/3/library/stdtypes.html#frozenset). [hash` ()](https://docs.python.org/3/reference/datamodel.html#object.__hash__),應(yīng)該返回一個整數(shù)。 僅有一個要求,具有相同的值的對象應(yīng)該有相同的散列值,應(yīng)該考慮以某種方式將散列值與在對象中比較中起作用的部分聯(lián)系起來(例如,用排斥或)。
注意:hash() 將返回值從一個對象的自定義 下一篇:復(fù)合語句