接上篇:[譯]Python 語言參考-3.2. 標(biāo)準(zhǔn)類型層次(上)
可調(diào)用類型
此類型表示可被函數(shù)(參考
Calls
章節(jié))調(diào)用:自定義函數(shù)(User-defined functions)
一個(gè)自定義函數(shù)對象被“函數(shù)定義說明”(參考函數(shù)定義章節(jié))創(chuàng)建岖是。它應(yīng)該能夠和與它的參數(shù)個(gè)數(shù)相等的參數(shù)列表一起士败,作為函數(shù)的正式參數(shù)寓涨。
特殊屬性:
屬性 含義 __doc__
函數(shù)的文檔字符串,如果不可用則為 None
涌哲;不會(huì)被子類繼承鼻吮。可寫 __name__
函數(shù)名当辐。 可寫 __qualname__
函數(shù)的合法名
3.3版本新添加。可寫 __module__
函數(shù)定義所在的模塊名晋渺,如果不可用則為 None
镰绎。可寫 __defaults__
一個(gè)包含默認(rèn)參數(shù)值的元組,該元組由擁有默認(rèn)值的參數(shù)的默認(rèn)值組成木西。如果沒有參數(shù)擁有默認(rèn)值畴栖,則返回 None
。可寫 __code__
代表編譯后函數(shù)體的代碼對象八千。 可寫 __globals__
一個(gè)包含函數(shù)全局變量——函數(shù)定義所在模塊的全局命名空間——的字典的引用吗讶。 只讀 __dict__
任意函數(shù)屬性的命名空間挪挤。 可寫 __closure__
None
或者包含為函數(shù)綁定自由變量格子的元組。只讀 __annotations__
包含參數(shù)注解的字典关翎。字典的鍵是參數(shù)名扛门,如果提供返回注解,則為 'return'
纵寝。可寫 __kwdefaults__
包含默認(rèn)的只限關(guān)鍵字參數(shù)的字典论寨。 可寫 多數(shù)被標(biāo)記為“可寫”的屬性在賦值時(shí)會(huì)檢查類型。
函數(shù)對象也支持獲人睢(getting)和設(shè)置(setting)任意可被使用的屬性葬凳,例如:將元數(shù)據(jù)綁定到函數(shù)上。常規(guī)屬性使用點(diǎn)號獲取室奏。注意火焰,當(dāng)前的實(shí)現(xiàn)僅支持自定義函數(shù)的屬性。將來的版本可能會(huì)支持內(nèi)建函數(shù)的屬性胧沫。
其他關(guān)于函數(shù)定義的信息可從它的代碼對象中解鎖昌简;參考下面的內(nèi)部類型描述。
實(shí)例方法
一個(gè)實(shí)例方法對象將一個(gè)類绒怨,一個(gè)類實(shí)例和任意可調(diào)用的對象(通常是自定義函數(shù))組合起來纯赎。
特殊的只讀屬性:__self__
是一個(gè)類實(shí)例對象,__func__
是一個(gè)函數(shù)對象南蹂;__doc__
是方法的文檔說明(和__func__.__doc__
一樣)犬金;__name__
是方法名(和__func__.__name__
一樣);__module__
是方法定義所在模塊的名稱六剥,如果不可用則為None
晚顷。方法也支持訪問任意底層函數(shù)的屬性,但不能設(shè)置屬性值疗疟。
當(dāng)獲取一個(gè)類的屬性時(shí)(也許通過該類的實(shí)例獲雀媚),如果屬性是一個(gè)自定義函數(shù)對象或一個(gè)類方法對象可能會(huì)創(chuàng)建自定義方法對象秃嗜。
當(dāng)一個(gè)實(shí)例方法對象通過檢索一個(gè)類實(shí)例的自定義函數(shù)對象創(chuàng)建時(shí)权均,它的
__self__
屬性是這個(gè)實(shí)例,方法對象稱為被綁定的對象锅锨。新方法的__func__
屬性是源函數(shù)對象叽赊。當(dāng)一個(gè)自定義函數(shù)對象通過檢索一個(gè)類或?qū)嵗钠渌椒▽ο髣?chuàng)建時(shí),它的行為和一個(gè)函數(shù)對象一致必搞。除非新實(shí)例的
__func__
屬性不是源生方法對象(除了它的__func__
屬性外)必指。當(dāng)通過檢索一個(gè)類或?qū)嵗念惙椒▽ο髣?chuàng)建一個(gè)實(shí)例方法對象時(shí),它的
__self__
屬性是類本身恕洲,它的__func__
屬性是底層類方法的函數(shù)對象塔橡。當(dāng)調(diào)用一個(gè)實(shí)例方法對象時(shí)梅割,底層函數(shù)(
__func__
)也被調(diào)用,將類實(shí)例(__self__
)插入?yún)?shù)列表的第一位葛家。對實(shí)例而言户辞,如果C
是一個(gè)包含對函數(shù)f()
的定義的類,x
是C
的實(shí)例癞谒,那么調(diào)用x.f(1)
和調(diào)用C.f(x, 1)
等價(jià)底燎。當(dāng)一個(gè)實(shí)例方法對象來源于一個(gè)類方法對象,存儲(chǔ)在
__self__
中的“類實(shí)例”是類本身弹砚,所以調(diào)用x.f(1)
或C.f(1)
都等價(jià)與調(diào)用f(C, 1)
双仍,此處f
是底層函數(shù)。需要注意的是桌吃,每次從實(shí)例中檢索屬性時(shí)朱沃,都會(huì)發(fā)生從函數(shù)對象到實(shí)例方法對象的轉(zhuǎn)換。在某些情況下茅诱,一個(gè)有效的優(yōu)化是給屬性賦予一個(gè)局部變量逗物,并使用該局部變量。這種轉(zhuǎn)換只發(fā)生在自定義函數(shù)中让簿;其他可調(diào)用對象(以及所有不可調(diào)用對象)檢索是不發(fā)生轉(zhuǎn)換敬察。還有一點(diǎn)需要注意,作為類屬性的自定義函數(shù)不能轉(zhuǎn)換為綁定函數(shù)尔当;這種情況值發(fā)生在該函數(shù)是類中的一個(gè)屬性時(shí)。
生成器函數(shù)(Generator functions)
一個(gè)使用了
yield
語句(參考yield 語句章節(jié))的函數(shù)或方法稱為生成器函數(shù)蹂安。當(dāng)調(diào)用此類函數(shù)是椭迎,會(huì)返回一個(gè)用于執(zhí)行函數(shù)體的迭代器對象:調(diào)用迭代器的iterator.__next__()
方法會(huì)執(zhí)行該函數(shù)直到它使用yield
語句返回一個(gè)值。當(dāng)函數(shù)執(zhí)行return
語句或者執(zhí)行到了最后田盈,會(huì)拋出一個(gè)StipIteration
異常畜号,這時(shí)迭代器已經(jīng)到達(dá)了待返回值集合的末尾。協(xié)同函數(shù)(Coroutine functions)
使用
async def
定義的函數(shù)或方法稱為協(xié)同函數(shù)允瞧。調(diào)用此類函數(shù)會(huì)返回一個(gè)協(xié)同程序(coroutine
)對象简软。它可能包含await
表達(dá)式,同async with
和async for
語句相同述暂。參考協(xié)同程序?qū)ο?/code>
章節(jié)痹升。內(nèi)建函數(shù)
內(nèi)建函數(shù)對象是對 C 函數(shù)的包裝。例如內(nèi)建函數(shù)
len()
和math.sin()
(math
是標(biāo)準(zhǔn)的內(nèi)建模塊)畦韭。參數(shù)類型和個(gè)數(shù)由 C 函數(shù)決定疼蛾。一些特殊的只讀屬性:__doc__
是函數(shù)的文檔字符串,如果不可用則為None
艺配;__name__
是函數(shù)名察郁;__self__
被設(shè)置為None
(but see the next item)衍慎;__module__
是函數(shù)定義所在模塊的名字,如果不可用則為None
皮钠。內(nèi)建方法
和內(nèi)建函數(shù)不同稳捆,內(nèi)建方法包含一個(gè)作為附加參數(shù)傳遞給 C 函數(shù)的對象。例如內(nèi)建方法
alist.append()
麦轰,假設(shè)alist是一個(gè)列表對象乔夯。這種情況下,特殊的只讀屬性__self__
被設(shè)置為alist指向的對象原朝。類
類是可調(diào)用的驯嘱。類一般作為它們自己創(chuàng)建對象的工廠存在,但類的變種可能會(huì)重寫
__new__()
函數(shù)喳坠。調(diào)用時(shí)會(huì)將參數(shù)傳遞給__new__()
鞠评,而通常情況下,都是傳遞給__init__()
來創(chuàng)建一個(gè)新實(shí)例壕鹉。類實(shí)例
任意類的實(shí)例只要在他們的類中定義一個(gè)
__call()__
函數(shù)剃幌,就都可被調(diào)用。
模塊(Modules)
模塊是 Python 代碼中一個(gè)基本的組織單位晾浴,被
import system
創(chuàng)建负乡,可通過import
語句(查看import),調(diào)用類似importlib.import_module()
函數(shù),或者內(nèi)建__import__()
函數(shù)調(diào)用脊凰。模塊對象有一個(gè)用字典對象(被定義在該模塊中的函數(shù)屬性__globals__
引用的字典)表示的命名空間抖棘。為了能在字典中查找,屬性引用會(huì)被轉(zhuǎn)化狸涌,例如:m.x
與m.__dict__["x"]
相同切省。模塊對象不包含實(shí)例化模塊的代碼對象(因?yàn)橐坏┠K初始化完畢,就不需要該對象了)帕胆。給屬性賦值會(huì)更新模塊的命名空間字典朝捆,例如:
m.x = 1
與m.__dict__["x"] = 1
相同。特殊的只讀屬性:
__dict__
是模塊的命名空間懒豹,以字典對象形式存在芙盘。CPython 實(shí)現(xiàn)細(xì)節(jié):根據(jù) CPython 清空模塊字典的方式,即使仍有可用引用指向模塊字典脸秽,它也會(huì)在模塊超出范圍后被清空儒老。為了避免這種情況發(fā)生,在直接使用模塊的字典時(shí)豹储,你可以拷貝該字典或確保模塊不超出范圍贷盲。
預(yù)定義可寫屬性:__name__
是模塊名;__doc__
是模塊的文檔字符串,如果不可用則為None
巩剖;如果從一個(gè)文件中加載模塊铝穷,則__file__
是加載該模塊的文件的路徑名。__file__
屬性在某些模塊中不存在佳魔,比如靜態(tài)鏈接到解釋器的 C 模塊曙聂;對于從共享庫中動(dòng)態(tài)加載的擴(kuò)展模塊而言,__file__
是共享庫文件的路徑名鞠鲜。
自定義類
自定義類型通常通過類定義說明(參考類定義說明章節(jié))創(chuàng)建宁脊。自定義類都有一個(gè)用字典對象表示的命名空間。為了能在字典中查找贤姆,屬性引用會(huì)被轉(zhuǎn)化榆苞。例如:
C.x
會(huì)轉(zhuǎn)化為C.__dict__["x"]
(盡管有一些允許通過其他方式定位屬性的鉤子)。當(dāng)屬性不在自定義類時(shí)霞捡,會(huì)繼續(xù)在基類中尋找該屬性坐漏。Python 使用 C3 方法解析順序(C3 method resolution order)在基類中查找,該方法即使在“寶石”繼承結(jié)構(gòu)(多個(gè)繼承路徑指向同一個(gè)祖先)中也表現(xiàn)得體碧信。 C3 MRO 的詳細(xì)信息可在伴隨 2.3 版本發(fā)行的文檔中查看:https://www.python.org/download/releases/2.3/mro/赊琳。當(dāng)一個(gè)類(比如類
C
)的屬性引用指向一個(gè)類方法對象時(shí),它會(huì)被轉(zhuǎn)化為__self__
屬性為 C 的實(shí)例方法對象砰碴。當(dāng)指向一個(gè)靜態(tài)方法對象是躏筏,它會(huì)被轉(zhuǎn)化為靜態(tài)方法對象的包裝對象。查看實(shí)現(xiàn)描述符章節(jié)中另一種從類中檢索的屬性的方法呈枉,此方法檢索出的屬性可能與在__dict__
中實(shí)際包含的不同趁尼。類的屬性賦值會(huì)更新類的字典,基類字典不會(huì)更新猖辫。
類對象可以被調(diào)用(參考上面)來指向一個(gè)類實(shí)例(參考下面)弱卡。
特殊屬性:
__name__
是類名;__module__
是類定義所在模塊的模塊名住册;__dict__
是包含類命名空間的字典;__bases__
是一個(gè)包含基類的元組(可能為空或單元組)瓮具,在基類列表中以它們出現(xiàn)的順序排列荧飞;__doc__
是類的文檔字符串,如果不可用則為None
名党。
類實(shí)例
類實(shí)例通過調(diào)用類對象創(chuàng)建(參考上面)叹阔。類實(shí)例有一個(gè)以字典形式實(shí)現(xiàn)的命名空間,該字典是檢索屬性引用時(shí)的首選位置传睹。當(dāng)屬性不在字典中耳幢,而實(shí)例對應(yīng)的類有此屬性時(shí),會(huì)繼續(xù)搜索類中的屬性。如果一個(gè)類的屬性是自定義函數(shù)對象睛藻,它會(huì)被轉(zhuǎn)化為一個(gè)
__self__
屬性是該實(shí)例的實(shí)例方法對象启上。靜態(tài)方法和類方法對象也會(huì)被轉(zhuǎn)化;參考上面的“類”店印。查看實(shí)現(xiàn)描述符章節(jié)中另一種從類實(shí)例中檢索類屬性的方法冈在,此方法檢索出的屬性可能與在類的__dict__
中實(shí)際包含的不同。如果類屬性沒有找到按摘,并且對象對應(yīng)的類有__getattr__()
方法包券,該方法會(huì)被調(diào)用以用來查找。賦值或刪除屬性會(huì)更新實(shí)例字典炫贤,類字典不會(huì)更新溅固。如果類有
__setattr__()
或__delattr__()
方法,該方法會(huì)被調(diào)用兰珍,而不是直接更新實(shí)例字典侍郭。如果類實(shí)例有一些特定名稱的方法,它們可以偽裝成數(shù)字俩垃,序列励幼,或者映射集合。參考特定方法名章節(jié)口柳。
特殊屬性:__dict__
是一個(gè)字典屬性苹粟;__class__
是一個(gè)實(shí)例對應(yīng)的類。
I/O 對象(也被稱為文件對象)
文件對象代表了一個(gè)打開的文件跃闹。有很多創(chuàng)建對象的捷徑:內(nèi)建函數(shù)
open()
嵌削,os.popen()
,os.fopen()
和 socket 對象的makefile()
方法(也可能通過其他擴(kuò)展模塊中的方法創(chuàng)建)望艺。
sys.stdin
苛秕,sys.stdout
,sys.stderr
對象被初始化為文件按對象找默,分別對應(yīng)解釋器的標(biāo)準(zhǔn)輸入艇劫,輸出和錯(cuò)誤流;它們都是以文本模式打開惩激,遵守符合io.TextIOBase
抽象類的接口定義店煞。
內(nèi)部類型
少數(shù)被解釋器內(nèi)部使用的類型暴露給了用戶。它們的定義可能會(huì)在在未來版本的解釋器中改變风钻,但是為了保持完整性顷蟀,此處還是提及了他們。
代碼對象(Code objects)
代碼對象代表字節(jié)編譯(byte-compiled)的可執(zhí)行 Python 代碼骡技,或者是字節(jié)碼鸣个。代碼對象和函數(shù)對象的區(qū)別在于:函數(shù)對象包含一個(gè)明確的對函數(shù)全局的引用(函數(shù)定義所在模塊),而代碼對象不包含上下文;而且默認(rèn)參數(shù)值會(huì)存在函數(shù)對象中囤萤,而不在代碼對象中昼窗,因?yàn)樗麄兇磉\(yùn)行時(shí)被計(jì)算出的值。不像函數(shù)對象阁将,代碼對象是不可變的而且不包含對(直接或繼承的)可變對象的引用膏秫。
特殊的制度屬性:
co_name
給出函數(shù)名;co_argcount
是位置參數(shù)(positional arguments)的個(gè)數(shù)(包含帶默認(rèn)值的參數(shù))做盅;co_nlocals
是供函數(shù)使用的局部變量(包含參數(shù))的個(gè)數(shù)缤削;co_varnames
是一個(gè)包含局部變量名的元組(從參數(shù)名開始);co_cellvars
是一個(gè)包含被嵌套函數(shù)引用的局部變量名的元組吹榴;co_freevars
是一個(gè)包含自由變量名的元組亭敢;co_code
是一個(gè)代表字節(jié)碼指令序列的字符串;co_consts
是一個(gè)包含字節(jié)碼使用的字面值的元組图筹;co_names
是一個(gè)包含被字節(jié)碼使用的名稱的元組帅刀;co_filename
是被編譯代碼所在的文件名;co_firstlineno
是函數(shù)的第一行的行號远剩;co_lnotab
是一個(gè)編碼從字節(jié)碼坐標(biāo)到行號的映射集合的字符串(查看解釋器源碼獲取詳細(xì)信息)扣溺;co_stacksize
是請求的棧大小(包括局部變量)瓜晤;co_flags
是一個(gè)編碼了一些解釋器標(biāo)識的整數(shù)锥余。以下是為
co_flags
定義的標(biāo)志位:如果函數(shù)使用了*arguments
語法來接受任意個(gè)位置參數(shù),則放置標(biāo)志位0x04
痢掠;如果函數(shù)使用了**keywords
語法來接受任意鍵值對參數(shù)驱犹,則放置標(biāo)識位0x08
;如果函數(shù)是一個(gè)生成器足画,則放置標(biāo)志位0x20
雄驹。將來特性聲明(
from __future__ import division
)也用co_flags
中的標(biāo)志位來標(biāo)識代碼對象使用一個(gè)指定特性編譯的功能是否開啟:如果函數(shù)使用將來版本編譯功能開啟,則放置標(biāo)志位0x2000
淹辞;在早期的 Python 版本中使用0x10
和0x1000
医舆。
co_flags
的其他標(biāo)志位僅供內(nèi)部使用。如果一個(gè)代碼對象代表一個(gè)函數(shù)象缀,那么
co_consts
的第一個(gè)元素是函數(shù)的文檔字符串彬向,如果不可達(dá)則為None
。幀對象(Frame objects)
幀對象代表執(zhí)行幀攻冷。他們可能會(huì)出現(xiàn)在跟蹤對象中(參考下面)。
特殊的只讀屬性:
f_back
指向之前的棧幀(用于調(diào)用者)遍希,如果當(dāng)前已經(jīng)在棧幀底部等曼,則為None
;f_code
是幀中將要被執(zhí)行的代碼對象;f_locals
是用來查找局部變量的字典禁谦;f_globals
是用來查找全局變量的字典胁黑;f_buitins
用于內(nèi)建(固有的)名字;f_lasti
給予精確地說明(是進(jìn)入到代碼對象字節(jié)碼字符串的索引)州泊。特殊的可寫屬性:
f_trace
如果不是None
丧蘸,則為在每行源碼開頭處被調(diào)用的函數(shù)(用來調(diào)試);f_lineno
是幀當(dāng)前的行號——在跟蹤函數(shù)內(nèi)部寫入此屬性遥皂,可以跳轉(zhuǎn)到指定行(只針對最底層的幀使用)力喷。通過向 f_lineno 寫入,調(diào)試者可以實(shí)現(xiàn)一個(gè)跳轉(zhuǎn)命令(也稱為設(shè)置下一條語句)演训。幀對象支持一個(gè)方法:
frame.clear()
此方法清空幀持有的所有局部變量引用弟孟。同時(shí),如果幀屬于一個(gè)生成器样悟,則生成器是最終化(finalized)的拂募。此方法有助于打破對幀對象的循環(huán)引用(例如:當(dāng)捕獲到一個(gè)異常并存儲(chǔ)它的跟蹤信息,以備后來使用)窟她。如果幀正在執(zhí)行陈症,則拋出
RuntimeError
異常。3.4版本新添加震糖。
跟蹤對象
跟蹤對象代表一個(gè)異常的堆棧蹤跡(stack trace)录肯。當(dāng)發(fā)生異常時(shí)跟蹤對象被創(chuàng)建。當(dāng)異常處理器展開執(zhí)行棧進(jìn)行搜索時(shí)试伙,在每個(gè)展開層次中的跟蹤對象都會(huì)插在當(dāng)前跟蹤對象的前面嘁信。當(dāng)異常處理器介入后,堆棧蹤跡對程序可訪問疏叨。(參照try 語句章節(jié)潘靖。)它作為被
sys.exc_info()
返回的tuple中的第三個(gè)元素被訪問。當(dāng)程序沒有合適的處理器時(shí)蚤蔓,堆棧蹤跡以良好的格式被寫入標(biāo)準(zhǔn)錯(cuò)誤流中卦溢;如果解釋器是交互式的,用戶也可以通過sys.last_traceback
獲取到它秀又。特殊的只讀屬性:
tb_next
表示堆棧蹤跡的下一個(gè)層次(指向程序發(fā)生異常處的幀)单寂,如果沒有下一層次則為None
;tb_frame
指向當(dāng)前層次的執(zhí)行幀吐辙;tb_lineno
給出發(fā)生異常處的行號宣决;tb_lasti
指的是精確的命令。在跟蹤對象中行號和最后一次指令可能與幀對象發(fā)生異常的行號不一致昏苏,如果該異常發(fā)生在try
語句中尊沸,并且沒有匹配的except
語句塊或finally
語句塊威沫。切片對象
切片對象代表
__getitem__()
方法中的切片。它們也可以通過內(nèi)建函數(shù)slice()
創(chuàng)建洼专。特殊的只讀屬性:
start
是前邊界棒掠;stop
是后邊界;step
是步值屁商;如果不提供值烟很,則為None
。這些屬性可以是任意類型蜡镶。切片對象支持一個(gè)方法:
slice.indices(self, length)
此方法有一個(gè)整型的參數(shù) length 并估算有關(guān)切片的信息雾袱,切片對象會(huì)描述是否應(yīng)用連續(xù)的 length 元素。該方法返回一個(gè)包含三個(gè)整型的元組帽哑;這三個(gè)整型分別代表
start
谜酒,stop
和step
或切片的步長。未提供或超出邊界的索引會(huì)按照符合正常切片的方法處理妻枕。靜態(tài)方法對象
靜態(tài)方法對象提供了阻止上述將函數(shù)對象轉(zhuǎn)換為方法對象的方法僻族。靜態(tài)方法對象是一個(gè)對其他對象的包裝,通常是一個(gè)自定義方法對象屡谐。當(dāng)一個(gè)靜態(tài)方法對象被類或類實(shí)例檢索時(shí)述么,該對象實(shí)際上會(huì)返回一個(gè)包裝對象,這個(gè)包裝對象不會(huì)再做任何轉(zhuǎn)換愕掏。靜態(tài)方法對象本身是不可調(diào)用的度秘,但它們的包裝類是調(diào)用的。靜態(tài)方法對象通過內(nèi)建構(gòu)造器
staticmethod()
方法創(chuàng)建饵撑。類方法對象
與靜態(tài)方法對象類似剑梳,類方法對象是一個(gè)其他對象的包裝,改變從類或類實(shí)例中檢索對象的方式滑潘。類對象的行為決定于“自定義方法”中描述的檢索方式垢乙。類方法對象通過內(nèi)建構(gòu)造器
classmethod()
創(chuàng)建。
譯者結(jié)語
翻譯真不是個(gè)好干的活语卤,真心累白反!但官方文檔真是寶啊粹舵,學(xué)到了很多東西钮孵,還需要慢慢消化理解。翻譯完后眼滤,有時(shí)間要做個(gè)總結(jié)文檔巴席。
限于譯者英文水平,如有翻譯不當(dāng)之處還請各位予以批評指正诅需。也希望感興趣的同學(xué)加入情妖,共同學(xué)習(xí)睬关,共同進(jìn)步。
PS:部分名詞中英對照:
英文 | 中文 |
---|---|
function | 函數(shù) |
method | 方法 |
object | 對象 |
instance | 實(shí)例 |
User-defind | 自定義 |