### 導航
- [索引](../genindex.xhtml "總目錄")
- [模塊](../py-modindex.xhtml "Python 模塊索引") |
- [下一頁](library.xhtml "代碼庫和插件 FAQ") |
- [上一頁](programming.xhtml "編程常見問題") |
- 
- [Python](https://www.python.org/) ?
- zh\_CN 3.7.3 [文檔](../index.xhtml) ?
- [Python 常見問題](index.xhtml) ?
- $('.inline-search').show(0); |
# [設計和歷史常見問題](#id2)
目錄
- [設計和歷史常見問題](#design-and-history-faq)
- [為什么Python使用縮進來分組語句?](#why-does-python-use-indentation-for-grouping-of-statements)
- [為什么簡單的算術運算得到奇怪的結果?](#why-am-i-getting-strange-results-with-simple-arithmetic-operations)
- [為什么浮點計算不準確?](#why-are-floating-point-calculations-so-inaccurate)
- [為什么Python字符串是不可變的?](#why-are-python-strings-immutable)
- [為什么必須在方法定義和調用中顯式使用“self”?](#why-must-self-be-used-explicitly-in-method-definitions-and-calls)
- [為什么不能在表達式中賦值?](#why-can-t-i-use-an-assignment-in-an-expression)
- [為什么Python對某些功能(例如list.index())使用方法來實現,而其他功能(例如len(List))使用函數實現?](#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list)
- [為什么 join()是一個字符串方法而不是列表或元組方法?](#why-is-join-a-string-method-instead-of-a-list-or-tuple-method)
- [異常有多快?](#how-fast-are-exceptions)
- [為什么Python中沒有switch或case語句?](#why-isn-t-there-a-switch-or-case-statement-in-python)
- [難道不能在解釋器中模擬線程,而非得依賴特定于操作系統的線程實現嗎?](#can-t-you-emulate-threads-in-the-interpreter-instead-of-relying-on-an-os-specific-thread-implementation)
- [為什么lambda表達式不能包含語句?](#why-can-t-lambda-expressions-contain-statements)
- [可以將Python編譯為機器代碼,C或其他語言嗎?](#can-python-be-compiled-to-machine-code-c-or-some-other-language)
- [Python如何管理內存?](#how-does-python-manage-memory)
- [為什么CPython不使用更傳統的垃圾回收方案?](#why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme)
- [CPython退出時為什么不釋放所有內存?](#why-isn-t-all-memory-freed-when-cpython-exits)
- [為什么有單獨的元組和列表數據類型?](#why-are-there-separate-tuple-and-list-data-types)
- [列表是如何在CPython中實現的?](#how-are-lists-implemented-in-cpython)
- [字典是如何在CPython中實現的?](#how-are-dictionaries-implemented-in-cpython)
- [為什么字典key必須是不可變的?](#why-must-dictionary-keys-be-immutable)
- [為什么 list.sort() 沒有返回排序列表?](#why-doesn-t-list-sort-return-the-sorted-list)
- [如何在Python中指定和實施接口規范?](#how-do-you-specify-and-enforce-an-interface-spec-in-python)
- [為什么沒有goto?](#why-is-there-no-goto)
- [為什么原始字符串(r-strings)不能以反斜杠結尾?](#why-can-t-raw-strings-r-strings-end-with-a-backslash)
- [為什么Python沒有屬性賦值的“with”語句?](#why-doesn-t-python-have-a-with-statement-for-attribute-assignments)
- [為什么 if/while/def/class語句需要冒號?](#why-are-colons-required-for-the-if-while-def-class-statements)
- [為什么Python在列表和元組的末尾允許使用逗號?](#why-does-python-allow-commas-at-the-end-of-lists-and-tuples)
## [為什么Python使用縮進來分組語句?](#id3)
Guido van Rossum 認為使用縮進進行分組非常優雅,并且大大提高了普通Python程序的清晰度。大多數人在一段時間后就學會并喜歡上這個功能。
由于沒有開始/結束括號,因此解析器感知的分組與人類讀者之間不會存在分歧。偶爾C程序員會遇到像這樣的代碼片段:
```
if (x <= y)
x++;
y--;
z++;
```
如果條件為真,則只執行 `x++` 語句,但縮進會使你認為情況并非如此。即使是經驗豐富的C程序員有時會長時間盯著它,想知道為什么即使 `x > y` , `y` 也在減少。
因為沒有開始/結束括號,所以Python不太容易發生編碼式沖突。在C中,括號可以放到許多不同的位置。如果您習慣于閱讀和編寫使用一種風格的代碼,那么在閱讀(或被要求編寫)另一種風格時,您至少會感到有些不安。
許多編碼風格將開始/結束括號單獨放在一行上。這使得程序相當長,浪費了寶貴的屏幕空間,使得更難以對程序進行全面的了解。理想情況下,函數應該適合一個屏幕(例如,20--30行)。 20行Python可以完成比20行C更多的工作。這不僅僅是由于缺少開始/結束括號 -- 缺少聲明和高級數據類型也是其中的原因 -- 但縮進基于語法肯定有幫助。
## [為什么簡單的算術運算得到奇怪的結果?](#id4)
請看下一個問題。
## [為什么浮點計算不準確?](#id5)
用戶經常對這樣的結果感到驚訝:
```
>>> 1.2 - 1.0
0.19999999999999996
```
并且認為這是 Python中的一個 bug。其實不是這樣。這與 Python 關系不大,而與底層平臺如何處理浮點數字關系更大。
CPython 中的 [`float`](../library/functions.xhtml#float "float") 類型使用C語言的 `double` 類型進行存儲。 [`float`](../library/functions.xhtml#float "float") 對象的值是以固定的精度(通常為 53 位)存儲的二進制浮點數,由于 Python 使用 C 操作,而后者依賴于處理器中的硬件實現來執行浮點運算。 這意味著就浮點運算而言,Python 的行為類似于許多流行的語言,包括 C 和 Java。
許多可以輕松地用十進制表示的數字不能用二進制浮點表示。例如,之后:
```
>>> x = 1.2
```
為 `x` 存儲的值是與十進制的值 `1.2` (非常接近) 的近似值,但不完全等于它。 在典型的機器上,實際存儲的值是:
```
1.0011001100110011001100110011001100110011001100110011 (binary)
```
確切地說:
```
1.1999999999999999555910790149937383830547332763671875 (decimal)
```
典型的 53 位精度為 Python 浮點數提供了 15-16 位小數的精度。
要獲得更完整的解釋,請參閱 Python 教程中的 [浮點算術](../tutorial/floatingpoint.xhtml#tut-fp-issues) 一章。
## [為什么Python字符串是不可變的?](#id6)
有幾個優點。
一個是性能:知道字符串是不可變的,意味著我們可以在創建時為它分配空間,并且存儲需求是固定不變的。這也是元組和列表之間區別的原因之一。
另一個優點是,Python 中的字符串被視為與數字一樣“基本”。 任何動作都不會將值 8 更改為其他值,在 Python 中,任何動作都不會將字符串 "8" 更改為其他值。
## [為什么必須在方法定義和調用中顯式使用“self”?](#id7)
這個想法借鑒了 Modula-3 語言。 出于多種原因它被證明是非常有用的。
首先,更明顯的顯示出,使用的是方法或實例屬性而不是局部變量。 閱讀 `self.x` 或 `self.meth()` 可以清楚地表明,即使您不知道類的定義,也會使用實例變量或方法。在 C++ 中,可以通過缺少局部變量聲明來判斷(假設全局變量很少見或容易識別) —— 但是在 Python 中沒有局部變量聲明,所以必須查找類定義才能確定。 一些 C++ 和 Java 編碼標準要求實例屬性具有 `m_` 前綴,因此這種顯式性在這些語言中仍然有用。
其次,這意味著如果要顯式引用或從特定類調用該方法,不需要特殊語法。 在 C++ 中,如果你想使用在派生類中重寫基類中的方法,你必須使用 `::` 運算符 -- 在 Python 中你可以編寫 `baseclass.methodname(self, <argument list>)`。 這對于 [`__init__()`](../reference/datamodel.xhtml#object.__init__ "object.__init__") 方法非常有用,特別是在派生類方法想要擴展同名的基類方法,而必須以某種方式調用基類方法時。
最后,它解決了變量賦值的語法問題:為了 Python 中的局部變量(根據定義!)在函數體中賦值的那些變量(并且沒有明確聲明為全局)賦值,就必須以某種方式告訴解釋器一個賦值是為了分配一個實例變量而不是一個局部變量,它最好是通過語法實現的(出于效率原因)。 C++ 通過聲明來做到這一點,但是 Python 沒有聲明,僅僅為了這個目的而引入它們會很可惜。 使用顯式的 `self.var` 很好地解決了這個問題。 類似地,對于使用實例變量,必須編寫 `self.var` 意味著對方法內部的非限定名稱的引用不必搜索實例的目錄。 換句話說,局部變量和實例變量存在于兩個不同的命名空間中,您需要告訴 Python 使用哪個命名空間。
## [為什么不能在表達式中賦值?](#id8)
許多習慣于C或Perl的人抱怨,他們想要使用C 的這個特性:
```
while (line = readline(f)) {
// do something with line
}
```
但在Python中被強制寫成這樣:
```
while True:
line = f.readline()
if not line:
break
... # do something with line
```
不允許在 Python 表達式中賦值的原因是這些其他語言中常見的、很難發現的錯誤,是由這個結構引起的:
```
if (x = 0) {
// error handling
}
else {
// code that only works for nonzero x
}
```
錯誤是一個簡單的錯字: `x = 0` ,將0賦給變量 `x` ,而比較 `x == 0` 肯定是可以預期的。
已經有許多替代方案提案。 大多數是為了少打一些字的黑客方案,但使用任意或隱含的語法或關鍵詞,并不符合語言變更提案的簡單標準:它應該直觀地向尚未被介紹到這一概念的人類讀者提供正確的含義。
一個有趣的現象是,大多數有經驗的Python程序員都認識到 `while True` 的習慣用法,也不太在意是否能在表達式構造中賦值; 只有新人表達了強烈的愿望希望將其添加到語言中。
有一種替代的拼寫方式看起來很有吸引力,但通常不如"while True"解決方案可靠:
```
line = f.readline()
while line:
... # do something with line...
line = f.readline()
```
問題在于,如果你改變主意(例如你想把它改成 `sys.stdin.readline()` ),如何知道下一行。你必須記住改變程序中的兩個地方 -- 第二次出現隱藏在循環的底部。
最好的方法是使用迭代器,這樣能通過 `for` 語句來循環遍歷對象。例如 [file objects](../glossary.xhtml#term-file-object) 支持迭代器協議,因此可以簡單地寫成:
```
for line in f:
... # do something with line...
```
## [為什么Python對某些功能(例如list.index())使用方法來實現,而其他功能(例如len(List))使用函數實現?](#id9)
正如Guido所說:
> (a) 對于某些操作,前綴表示法比后綴更容易閱讀 -- 前綴(和中綴!)運算在數學中有著悠久的傳統,就像在視覺上幫助數學家思考問題的記法。比較一下我們將 x\*(a+b) 這樣的公式改寫為 x\*a+x\*b 的容易程度,以及使用原始OO符號做相同事情的笨拙程度。
>
> (b) 當讀到寫有len(X)的代碼時,就知道它要求的是某件東西的長度。這告訴我們兩件事:結果是一個整數,參數是某種容器。相反,當閱讀x.len()時,必須已經知道x是某種實現接口的容器,或者是從具有標準len()的類繼承的容器。當沒有實現映射的類有get()或key()方法,或者不是文件的類有write()方法時,我們偶爾會感到困惑。
>
> —<https://mail.python.org/pipermail/python-3000/2006-November/004643.html>
## [為什么 join()是一個字符串方法而不是列表或元組方法?](#id10)
從Python 1.6開始,字符串變得更像其他標準類型,當添加方法時,這些方法提供的功能與始終使用String模塊的函數時提供的功能相同。這些新方法中的大多數已被廣泛接受,但似乎讓一些程序員感到不舒服的一種方法是:
```
", ".join(['1', '2', '4', '8', '16'])
```
結果如下:
```
"1, 2, 4, 8, 16"
```
反對這種用法有兩個常見的論點。
第一條是這樣的:“使用字符串文本(String Constant)的方法看起來真的很難看”,答案是也許吧,但是字符串文本只是一個固定值。如果在綁定到字符串的名稱上允許使用這些方法,則沒有邏輯上的理由使其在文字上不可用。
第二個異議通常是這樣的:“我實際上是在告訴序列使用字符串常量將其成員連接在一起”。遺憾的是并非如此。出于某種原因,把 [`split()`](../library/stdtypes.xhtml#str.split "str.split") 作為一個字符串方法似乎要容易得多,因為在這種情況下,很容易看到:
```
"1, 2, 4, 8, 16".split(", ")
```
是對字符串文本的指令,用于返回由給定分隔符分隔的子字符串(或在默認情況下,返回任意空格)。
[`join()`](../library/stdtypes.xhtml#str.join "str.join") 是字符串方法,因為在使用該方法時,您告訴分隔符字符串去迭代一個字符串序列,并在相鄰元素之間插入自身。此方法的參數可以是任何遵循序列規則的對象,包括您自己定義的任何新的類。對于字節和字節數組對象也有類似的方法。
## [異常有多快?](#id11)
如果沒有引發異常,則try/except塊的效率極高。實際上捕獲異常是昂貴的。在2.0之前的Python版本中,通常使用這個習慣用法:
```
try:
value = mydict[key]
except KeyError:
mydict[key] = getvalue(key)
value = mydict[key]
```
只有當你期望dict在任何時候都有key時,這才有意義。如果不是這樣的話,你就是應該這樣編碼:
```
if key in mydict:
value = mydict[key]
else:
value = mydict[key] = getvalue(key)
```
對于這種特定的情況,您還可以使用 `value = dict.setdefault(key, getvalue(key))`,但前提是調用 `getvalue()` 足夠便宜,因為在所有情況下都會對其進行評估。
## [為什么Python中沒有switch或case語句?](#id12)
你可以通過一系列 `if... elif... elif... else`.輕松完成這項工作。對于switch語句語法已經有了一些建議,但尚未就是否以及如何進行范圍測試達成共識。有關完整的詳細信息和當前狀態,請參閱 [**PEP 275**](https://www.python.org/dev/peps/pep-0275) \[https://www.python.org/dev/peps/pep-0275\] 。
對于需要從大量可能性中進行選擇的情況,可以創建一個字典,將case 值映射到要調用的函數。例如:
```
def function_1(...):
...
functions = {'a': function_1,
'b': function_2,
'c': self.method_1, ...}
func = functions[value]
func()
```
對于對象調用方法,可以通過使用 [`getattr()`](../library/functions.xhtml#getattr "getattr") 內置檢索具有特定名稱的方法來進一步簡化:
```
def visit_a(self, ...):
...
...
def dispatch(self, value):
method_name = 'visit_' + str(value)
method = getattr(self, method_name)
method()
```
建議對方法名使用前綴,例如本例中的 `visit_` 。如果沒有這樣的前綴,如果值來自不受信任的源,攻擊者將能夠調用對象上的任何方法。
## [難道不能在解釋器中模擬線程,而非得依賴特定于操作系統的線程實現嗎?](#id13)
答案1: 不幸的是,解釋器為每個Python堆棧幀推送至少一個C堆棧幀。此外,擴展可以隨時回調Python。因此,一個完整的線程實現需要對C的線程支持。
答案2: 幸運的是, [Stackless Python](https://github.com/stackless-dev/stackless/wiki) \[https://github.com/stackless-dev/stackless/wiki\] 有一個完全重新設計的解釋器循環,可以避免C堆棧。
## [為什么lambda表達式不能包含語句?](#id14)
Python的 lambda表達式不能包含語句,因為Python的語法框架不能處理嵌套在表達式內部的語句。然而,在Python中,這并不是一個嚴重的問題。與其他語言中添加功能的lambda表單不同,Python的 lambdas只是一種速記符號,如果您懶得定義函數的話。
函數已經是Python中的第一類對象,可以在本地范圍內聲明。 因此,使用lambda而不是本地定義的函數的唯一優點是你不需要為函數創建一個名稱 -- 這只是一個分配了函數對象(與lambda表達式生成的對象類型完全相同)的局部變量!
## [可以將Python編譯為機器代碼,C或其他語言嗎?](#id15)
[Cython](http://cython.org/) \[http://cython.org/\] 將帶有可選注釋的Python修改版本編譯到C擴展中。 [Nuitka](http://www.nuitka.net/) \[http://www.nuitka.net/\] 是一個將Python編譯成 C++ 代碼的新興編譯器,旨在支持完整的Python語言。要編譯成Java,可以考慮 [VOC](https://voc.readthedocs.io) \[https://voc.readthedocs.io\] 。
## [Python如何管理內存?](#id16)
Python 內存管理的細節取決于實現。 Python 的標準實現 [CPython](../glossary.xhtml#term-cpython) 使用引用計數來檢測不可訪問的對象,并使用另一種機制來收集引用循環,定期執行循環檢測算法來查找不可訪問的循環并刪除所涉及的對象。 [`gc`](../library/gc.xhtml#module-gc "gc: Interface to the cycle-detecting garbage collector.") 模塊提供了執行垃圾回收、獲取調試統計信息和優化收集器參數的函數。
但是,其他實現(如 [Jython](http://www.jython.org) \[http://www.jython.org\] 或 [PyPy](http://www.pypy.org) \[http://www.pypy.org\] ),)可以依賴不同的機制,如完全的垃圾回收器 。如果你的Python代碼依賴于引用計數實現的行為,則這種差異可能會導致一些微妙的移植問題。
在一些Python實現中,以下代碼(在CPython中工作的很好)可能會耗盡文件描述符:
```
for file in very_long_list_of_files:
f = open(file)
c = f.read(1)
```
實際上,使用CPython的引用計數和析構函數方案, 每個新賦值的 *f* 都會關閉前一個文件。然而,對于傳統的GC,這些文件對象只能以不同的時間間隔(可能很長的時間間隔)被收集(和關閉)。
如果要編寫可用于任何python實現的代碼,則應顯式關閉該文件或使用 [`with`](../reference/compound_stmts.xhtml#with) 語句;無論內存管理方案如何,這都有效:
```
for file in very_long_list_of_files:
with open(file) as f:
c = f.read(1)
```
## [為什么CPython不使用更傳統的垃圾回收方案?](#id17)
首先,這不是C標準特性,因此不能移植。(是的,我們知道Boehm GC庫。它包含了 *大多數* 常見平臺(但不是所有平臺)的匯編代碼,盡管它基本上是透明的,但也不是完全透明的; 要讓Python使用它,需要使用補丁。)
當Python嵌入到其他應用程序中時,傳統的GC也成為一個問題。在獨立的Python中,可以用GC庫提供的版本替換標準的malloc()和free(),嵌入Python的應用程序可能希望用 *它自己* 替代malloc()和free(),而可能不需要Python的。現在,CPython可以正確地實現malloc()和free()。
## [CPython退出時為什么不釋放所有內存?](#id18)
當Python退出時,從全局命名空間或Python模塊引用的對象并不總是被釋放。 如果存在循環引用,則可能發生這種情況 C庫分配的某些內存也是不可能釋放的(例如像Purify這樣的工具會抱怨這些內容)。 但是,Python在退出時清理內存并嘗試銷毀每個對象。
如果要強制 Python 在釋放時刪除某些內容,請使用 [`atexit`](../library/atexit.xhtml#module-atexit "atexit: Register and execute cleanup functions.") 模塊運行一個函數,強制刪除這些內容。
## [為什么有單獨的元組和列表數據類型?](#id19)
雖然列表和元組在許多方面是相似的,但它們的使用方式通常是完全不同的。可以認為元組類似于Pascal記錄或C結構;它們是相關數據的小集合,可以是不同類型的數據,可以作為一個組進行操作。例如,笛卡爾坐標適當地表示為兩個或三個數字的元組。
另一方面,列表更像其他語言中的數組。它們傾向于持有不同數量的對象,所有對象都具有相同的類型,并且逐個操作。例如, `os.listdir('.')` 返回表示當前目錄中的文件的字符串列表。如果向目錄中添加了一兩個文件,對此輸出進行操作的函數通常不會中斷。
元組是不可變的,這意味著一旦創建了元組,就不能用新值替換它的任何元素。列表是可變的,這意味著您始終可以更改列表的元素。只有不變元素可以用作字典的key,因此只能將元組和非列表用作key。
## [列表是如何在CPython中實現的?](#id20)
CPython的列表實際上是可變長度的數組,而不是lisp風格的鏈表。該實現使用對其他對象的引用的連續數組,并在列表頭結構中保留指向該數組和數組長度的指針。
這使得索引列表 `a[i]` 的操作成本與列表的大小或索引的值無關。
當添加或插入項時,將調整引用數組的大小。并采用了一些巧妙的方法來提高重復添加項的性能; 當數組必須增長時,會分配一些額外的空間,以便在接下來的幾次中不需要實際調整大小。
## [字典是如何在CPython中實現的?](#id21)
CPython的字典實現為可調整大小的哈希表。與B-樹相比,這在大多數情況下為查找(目前最常見的操作)提供了更好的性能,并且實現更簡單。
字典的工作方式是使用 [`hash()`](../library/functions.xhtml#hash "hash") 內置函數計算字典中存儲的每個鍵的hash代碼。hash代碼根據鍵和每個進程的種子而變化很大;例如,"Python" 的hash值為-539294296,而"python"(一個按位不同的字符串)的hash值為1142331976。然后,hash代碼用于計算內部數組中將存儲該值的位置。假設您存儲的鍵都具有不同的hash值,這意味著字典需要恒定的時間 -- O(1),用Big-O表示法 -- 來檢索一個鍵。
## [為什么字典key必須是不可變的?](#id22)
字典的哈希表實現使用從鍵值計算的哈希值來查找鍵。如果鍵是可變對象,則其值可能會發生變化,因此其哈希值也會發生變化。但是,由于無論誰更改鍵對象都無法判斷它是否被用作字典鍵值,因此無法在字典中修改條目。然后,當你嘗試在字典中查找相同的對象時,將無法找到它,因為其哈希值不同。如果你嘗試查找舊值,也不會找到它,因為在該哈希表中找到的對象的值會有所不同。
如果你想要一個用列表索引的字典,只需先將列表轉換為元組;用函數 `tuple(L)` 創建一個元組,其條目與列表 `L` 相同。 元組是不可變的,因此可以用作字典鍵。
已經提出的一些不可接受的解決方案:
- 哈希按其地址(對象ID)列出。這不起作用,因為如果你構造一個具有相同值的新列表,它將無法找到;例如:
```
mydict = {[1, 2]: '12'}
print(mydict[[1, 2]])
```
會引發一個 [`KeyError`](../library/exceptions.xhtml#KeyError "KeyError") 異常,因為第二行中使用的 `[1, 2]` 的 id 與第一行中的 id 不同。換句話說,應該使用 `==` 來比較字典鍵,而不是使用 [`is`](../reference/expressions.xhtml#is) 。
- 使用列表作為鍵時進行復制。這沒有用的,因為作為可變對象的列表可以包含對自身的引用,然后復制代碼將進入無限循環。
- 允許列表作為鍵,但告訴用戶不要修改它們。當你意外忘記或修改列表時,這將產生程序中的一類難以跟蹤的錯誤。它還使一個重要的字典不變量無效: `d.keys()` 中的每個值都可用作字典的鍵。
- 將列表用作字典鍵后,應標記為其只讀。問題是,它不僅僅是可以改變其值的頂級對象;你可以使用包含列表作為鍵的元組。將任何內容作為鍵關聯到字典中都需要將從那里可到達的所有對象標記為只讀 —— 并且自引用對象可能會導致無限循環。
如果需要,可以使用以下方法來解決這個問題,但使用它需要你自擔風險:你可以將一個可變結構包裝在一個類實例中,該實例同時具有 [`__eq__()`](../reference/datamodel.xhtml#object.__eq__ "object.__eq__") 和 [`__hash__()`](../reference/datamodel.xhtml#object.__hash__ "object.__hash__") 方法。然后,你必須確保駐留在字典(或其他基于 hash 的結構)中的所有此類包裝器對象的哈希值在對象位于字典(或其他結構)中時保持固定。:
```
class ListWrapper:
def __init__(self, the_list):
self.the_list = the_list
def __eq__(self, other):
return self.the_list == other.the_list
def __hash__(self):
l = self.the_list
result = 98767 - len(l)*555
for i, el in enumerate(l):
try:
result = result + (hash(el) % 9999999) * 1001 + i
except Exception:
result = (result % 7777777) + i * 333
return result
```
注意,哈希計算由于列表的某些成員可能不可用以及算術溢出的可能性而變得復雜。
此外,必須始終如此,如果 `o1 == o2` (即 `o1.__eq__(o2) is True` )則 `hash(o1) == hash(o2)``(即 ``o1.__hash__() == o2.__hash__()` ),無論對象是否在字典中。 如果你不能滿足這些限制,字典和其他基于 hash 的結構將會出錯。
對于 ListWrapper ,只要包裝器對象在字典中,包裝列表就不能更改以避免異常。除非你準備好認真考慮需求以及不正確地滿足這些需求的后果,否則不要這樣做。請留意。
## [為什么 list.sort() 沒有返回排序列表?](#id23)
在性能很重要的情況下,僅僅為了排序而復制一份列表將是一種浪費。因此, [`list.sort()`](../library/stdtypes.xhtml#list.sort "list.sort") 對列表進行了適當的排序。為了提醒您這一事實,它不會返回已排序的列表。這樣,當您需要排序的副本,但也需要保留未排序的版本時,就不會意外地覆蓋列表。
如果要返回新列表,請使用內置 [`sorted()`](../library/functions.xhtml#sorted "sorted") 函數。此函數從提供的可迭代列表中創建新列表,對其進行排序并返回。例如,下面是如何迭代遍歷字典并按keys排序:
```
for key in sorted(mydict):
... # do whatever with mydict[key]...
```
## [如何在Python中指定和實施接口規范?](#id24)
由C++和Java等語言提供的模塊接口規范描述了模塊的方法和函數的原型。許多人認為接口規范的編譯時強制執行有助于構建大型程序。
Python 2.6添加了一個 [`abc`](../library/abc.xhtml#module-abc "abc: Abstract base classes according to PEP 3119.") 模塊,允許定義抽象基類 (ABCs)。然后可以使用 [`isinstance()`](../library/functions.xhtml#isinstance "isinstance") 和 [`issubclass()`](../library/functions.xhtml#issubclass "issubclass") 來檢查實例或類是否實現了特定的ABC。 [`collections.abc`](../library/collections.abc.xhtml#module-collections.abc "collections.abc: Abstract base classes for containers") 模塊定義了一組有用的ABCs 例如 [`Iterable`](../library/collections.abc.xhtml#collections.abc.Iterable "collections.abc.Iterable") , [`Container`](../library/collections.abc.xhtml#collections.abc.Container "collections.abc.Container") , 和 [`MutableMapping`](../library/collections.abc.xhtml#collections.abc.MutableMapping "collections.abc.MutableMapping")
對于Python,通過對組件進行適當的測試規程,可以獲得接口規范的許多好處。還有一個工具PyChecker,可用于查找由于子類化引起的問題。
一個好的模塊測試套件既可以提供回歸測試,也可以作為模塊接口規范和一組示例。許多Python模塊可以作為腳本運行,以提供簡單的“自我測試”。即使是使用復雜外部接口的模塊,也常常可以使用外部接口的簡單“樁代碼(stub)”模擬進行隔離測試。可以使用 [`doctest`](../library/doctest.xhtml#module-doctest "doctest: Test pieces of code within docstrings.") 和 [`unittest`](../library/unittest.xhtml#module-unittest "unittest: Unit testing framework for Python.") 模塊或第三方測試框架來構造詳盡的測試套件,以運行模塊中的每一行代碼。
適當的測試規程可以幫助在Python中構建大型的、復雜的應用程序以及接口規范。事實上,它可能會更好,因為接口規范不能測試程序的某些屬性。例如, `append()` 方法將向一些內部列表的末尾添加新元素;接口規范不能測試您的 `append()` 實現是否能夠正確執行此操作,但是在測試套件中檢查這個屬性是很簡單的。
編寫測試套件非常有用,您可能希望設計代碼時著眼于使其易于測試。一種日益流行的技術是面向測試的開發,它要求在編寫任何實際代碼之前,首先編寫測試套件的各個部分。當然,Python允許您草率行事,根本不編寫測試用例。
## [為什么沒有goto?](#id25)
可以使用異常捕獲來提供 “goto結構” ,甚至可以跨函數調用工作的 。許多人認為異常捕獲可以方便地模擬C,Fortran和其他語言的 "go" 或 "goto" 結構的所有合理用法。例如:
```
class label(Exception): pass # declare a label
try:
...
if condition: raise label() # goto label
...
except label: # where to goto
pass
...
```
但是不允許你跳到循環的中間,這通常被認為是濫用goto。謹慎使用。
## [為什么原始字符串(r-strings)不能以反斜杠結尾?](#id26)
更準確地說,它們不能以奇數個反斜杠結束:結尾處的不成對反斜杠會轉義結束引號字符,留下未結束的字符串。
原始字符串的設計是為了方便想要執行自己的反斜杠轉義處理的處理器(主要是正則表達式引擎)創建輸入。此類處理器將不匹配的尾隨反斜杠視為錯誤,因此原始字符串不允許這樣做。反過來,允許通過使用引號字符轉義反斜杠轉義字符串。當r-string用于它們的預期目的時,這些規則工作的很好。
如果您正在嘗試構建Windows路徑名,請注意所有Windows系統調用都使用正斜杠:
```
f = open("/mydir/file.txt") # works fine!
```
如果您正在嘗試為DOS命令構建路徑名,請嘗試以下示例
```
dir = r"\this\is\my\dos\dir" "\\"
dir = r"\this\is\my\dos\dir\ "[:-1]
dir = "\\this\\is\\my\\dos\\dir\\"
```
## [為什么Python沒有屬性賦值的“with”語句?](#id27)
Python有一個 'with' 語句,它封裝了塊的執行,在塊的入口和出口調用代碼。有些語言的結構是這樣的:
```
with obj:
a = 1 # equivalent to obj.a = 1
total = total + 1 # obj.total = obj.total + 1
```
在Python中,這樣的結構是不明確的。
其他語言,如ObjectPascal、Delphi和C++ 使用靜態類型,因此可以毫不含糊地知道分配給什么成員。這是靜態類型的要點 -- 編譯器 *總是* 在編譯時知道每個變量的作用域。
Python使用動態類型。事先不可能知道在運行時引用哪個屬性。可以動態地在對象中添加或刪除成員屬性。這使得無法通過簡單的閱讀就知道引用的是什么屬性:局部屬性、全局屬性還是成員屬性?
例如,采用以下不完整的代碼段:
```
def foo(a):
with a:
print(x)
```
該代碼段假設 "a" 必須有一個名為 "x" 的成員屬性。然而,Python中并沒有告訴解釋器這一點。假設 "a" 是整數,會發生什么?如果有一個名為 "x" 的全局變量,它是否會在with塊中使用?如您所見,Python的動態特性使得這樣的選擇更加困難。
然而,Python 可以通過賦值輕松實現 "with" 和類似語言特性(減少代碼量)的主要好處。代替:
```
function(args).mydict[index][index].a = 21
function(args).mydict[index][index].b = 42
function(args).mydict[index][index].c = 63
```
寫成這樣:
```
ref = function(args).mydict[index][index]
ref.a = 21
ref.b = 42
ref.c = 63
```
這也具有提高執行速度的副作用,因為Python在運行時解析名稱綁定,而第二個版本只需要執行一次解析。
## [為什么 if/while/def/class語句需要冒號?](#id28)
冒號主要用于增強可讀性(ABC語言實驗的結果之一)。考慮一下這個:
```
if a == b
print(a)
```
與
```
if a == b:
print(a)
```
注意第二種方法稍微容易一些。請進一步注意,在這個FAQ解答的示例中,冒號是如何設置的;這是英語中的標準用法。
另一個次要原因是冒號使帶有語法突出顯示的編輯器更容易工作;他們可以尋找冒號來決定何時需要增加縮進,而不必對程序文本進行更精細的解析。
## [為什么Python在列表和元組的末尾允許使用逗號?](#id29)
Python 允許您在列表,元組和字典的末尾添加一個尾隨逗號:
```
[1, 2, 3,]
('a', 'b', 'c',)
d = {
"A": [1, 5],
"B": [6, 7], # last trailing comma is optional but good style
}
```
有幾個理由允許這樣做。
如果列表,元組或字典的字面值分布在多行中,則更容易添加更多元素,因為不必記住在上一行中添加逗號。這些行也可以重新排序,而不會產生語法錯誤。
不小心省略逗號會導致難以診斷的錯誤。例如:
```
x = [
"fee",
"fie"
"foo",
"fum"
]
```
這個列表看起來有四個元素,但實際上包含三個 : "fee", "fiefoo" 和 "fum" 。總是加上逗號可以避免這個錯誤的來源。
允許尾隨逗號也可以使編程代碼更容易生成。
### 導航
- [索引](../genindex.xhtml "總目錄")
- [模塊](../py-modindex.xhtml "Python 模塊索引") |
- [下一頁](library.xhtml "代碼庫和插件 FAQ") |
- [上一頁](programming.xhtml "編程常見問題") |
- 
- [Python](https://www.python.org/) ?
- zh\_CN 3.7.3 [文檔](../index.xhtml) ?
- [Python 常見問題](index.xhtml) ?
- $('.inline-search').show(0); |
? [版權所有](../copyright.xhtml) 2001-2019, Python Software Foundation.
Python 軟件基金會是一個非盈利組織。 [請捐助。](https://www.python.org/psf/donations/)
最后更新于 5月 21, 2019. [發現了問題](../bugs.xhtml)?
使用[Sphinx](http://sphinx.pocoo.org/)1.8.4 創建。
- Python文檔內容
- Python 有什么新變化?
- Python 3.7 有什么新變化
- 摘要 - 發布重點
- 新的特性
- 其他語言特性修改
- 新增模塊
- 改進的模塊
- C API 的改變
- 構建的改變
- 性能優化
- 其他 CPython 實現的改變
- 已棄用的 Python 行為
- 已棄用的 Python 模塊、函數和方法
- 已棄用的 C API 函數和類型
- 平臺支持的移除
- API 與特性的移除
- 移除的模塊
- Windows 專屬的改變
- 移植到 Python 3.7
- Python 3.7.1 中的重要變化
- Python 3.7.2 中的重要變化
- Python 3.6 有什么新變化A
- 摘要 - 發布重點
- 新的特性
- 其他語言特性修改
- 新增模塊
- 改進的模塊
- 性能優化
- Build and C API Changes
- 其他改進
- 棄用
- 移除
- 移植到Python 3.6
- Python 3.6.2 中的重要變化
- Python 3.6.4 中的重要變化
- Python 3.6.5 中的重要變化
- Python 3.6.7 中的重要變化
- Python 3.5 有什么新變化
- 摘要 - 發布重點
- 新的特性
- 其他語言特性修改
- 新增模塊
- 改進的模塊
- Other module-level changes
- 性能優化
- Build and C API Changes
- 棄用
- 移除
- Porting to Python 3.5
- Notable changes in Python 3.5.4
- What's New In Python 3.4
- 摘要 - 發布重點
- 新的特性
- 新增模塊
- 改進的模塊
- CPython Implementation Changes
- 棄用
- 移除
- Porting to Python 3.4
- Changed in 3.4.3
- What's New In Python 3.3
- 摘要 - 發布重點
- PEP 405: Virtual Environments
- PEP 420: Implicit Namespace Packages
- PEP 3118: New memoryview implementation and buffer protocol documentation
- PEP 393: Flexible String Representation
- PEP 397: Python Launcher for Windows
- PEP 3151: Reworking the OS and IO exception hierarchy
- PEP 380: Syntax for Delegating to a Subgenerator
- PEP 409: Suppressing exception context
- PEP 414: Explicit Unicode literals
- PEP 3155: Qualified name for classes and functions
- PEP 412: Key-Sharing Dictionary
- PEP 362: Function Signature Object
- PEP 421: Adding sys.implementation
- Using importlib as the Implementation of Import
- 其他語言特性修改
- A Finer-Grained Import Lock
- Builtin functions and types
- 新增模塊
- 改進的模塊
- 性能優化
- Build and C API Changes
- 棄用
- Porting to Python 3.3
- What's New In Python 3.2
- PEP 384: Defining a Stable ABI
- PEP 389: Argparse Command Line Parsing Module
- PEP 391: Dictionary Based Configuration for Logging
- PEP 3148: The concurrent.futures module
- PEP 3147: PYC Repository Directories
- PEP 3149: ABI Version Tagged .so Files
- PEP 3333: Python Web Server Gateway Interface v1.0.1
- 其他語言特性修改
- New, Improved, and Deprecated Modules
- 多線程
- 性能優化
- Unicode
- Codecs
- 文檔
- IDLE
- Code Repository
- Build and C API Changes
- Porting to Python 3.2
- What's New In Python 3.1
- PEP 372: Ordered Dictionaries
- PEP 378: Format Specifier for Thousands Separator
- 其他語言特性修改
- New, Improved, and Deprecated Modules
- 性能優化
- IDLE
- Build and C API Changes
- Porting to Python 3.1
- What's New In Python 3.0
- Common Stumbling Blocks
- Overview Of Syntax Changes
- Changes Already Present In Python 2.6
- Library Changes
- PEP 3101: A New Approach To String Formatting
- Changes To Exceptions
- Miscellaneous Other Changes
- Build and C API Changes
- 性能
- Porting To Python 3.0
- What's New in Python 2.7
- The Future for Python 2.x
- Changes to the Handling of Deprecation Warnings
- Python 3.1 Features
- PEP 372: Adding an Ordered Dictionary to collections
- PEP 378: Format Specifier for Thousands Separator
- PEP 389: The argparse Module for Parsing Command Lines
- PEP 391: Dictionary-Based Configuration For Logging
- PEP 3106: Dictionary Views
- PEP 3137: The memoryview Object
- 其他語言特性修改
- New and Improved Modules
- Build and C API Changes
- Other Changes and Fixes
- Porting to Python 2.7
- New Features Added to Python 2.7 Maintenance Releases
- Acknowledgements
- Python 2.6 有什么新變化
- Python 3.0
- Changes to the Development Process
- PEP 343: The 'with' statement
- PEP 366: Explicit Relative Imports From a Main Module
- PEP 370: Per-user site-packages Directory
- PEP 371: The multiprocessing Package
- PEP 3101: Advanced String Formatting
- PEP 3105: print As a Function
- PEP 3110: Exception-Handling Changes
- PEP 3112: Byte Literals
- PEP 3116: New I/O Library
- PEP 3118: Revised Buffer Protocol
- PEP 3119: Abstract Base Classes
- PEP 3127: Integer Literal Support and Syntax
- PEP 3129: Class Decorators
- PEP 3141: A Type Hierarchy for Numbers
- 其他語言特性修改
- New and Improved Modules
- Deprecations and Removals
- Build and C API Changes
- Porting to Python 2.6
- Acknowledgements
- What's New in Python 2.5
- PEP 308: Conditional Expressions
- PEP 309: Partial Function Application
- PEP 314: Metadata for Python Software Packages v1.1
- PEP 328: Absolute and Relative Imports
- PEP 338: Executing Modules as Scripts
- PEP 341: Unified try/except/finally
- PEP 342: New Generator Features
- PEP 343: The 'with' statement
- PEP 352: Exceptions as New-Style Classes
- PEP 353: Using ssize_t as the index type
- PEP 357: The 'index' method
- 其他語言特性修改
- New, Improved, and Removed Modules
- Build and C API Changes
- Porting to Python 2.5
- Acknowledgements
- What's New in Python 2.4
- PEP 218: Built-In Set Objects
- PEP 237: Unifying Long Integers and Integers
- PEP 289: Generator Expressions
- PEP 292: Simpler String Substitutions
- PEP 318: Decorators for Functions and Methods
- PEP 322: Reverse Iteration
- PEP 324: New subprocess Module
- PEP 327: Decimal Data Type
- PEP 328: Multi-line Imports
- PEP 331: Locale-Independent Float/String Conversions
- 其他語言特性修改
- New, Improved, and Deprecated Modules
- Build and C API Changes
- Porting to Python 2.4
- Acknowledgements
- What's New in Python 2.3
- PEP 218: A Standard Set Datatype
- PEP 255: Simple Generators
- PEP 263: Source Code Encodings
- PEP 273: Importing Modules from ZIP Archives
- PEP 277: Unicode file name support for Windows NT
- PEP 278: Universal Newline Support
- PEP 279: enumerate()
- PEP 282: The logging Package
- PEP 285: A Boolean Type
- PEP 293: Codec Error Handling Callbacks
- PEP 301: Package Index and Metadata for Distutils
- PEP 302: New Import Hooks
- PEP 305: Comma-separated Files
- PEP 307: Pickle Enhancements
- Extended Slices
- 其他語言特性修改
- New, Improved, and Deprecated Modules
- Pymalloc: A Specialized Object Allocator
- Build and C API Changes
- Other Changes and Fixes
- Porting to Python 2.3
- Acknowledgements
- What's New in Python 2.2
- 概述
- PEPs 252 and 253: Type and Class Changes
- PEP 234: Iterators
- PEP 255: Simple Generators
- PEP 237: Unifying Long Integers and Integers
- PEP 238: Changing the Division Operator
- Unicode Changes
- PEP 227: Nested Scopes
- New and Improved Modules
- Interpreter Changes and Fixes
- Other Changes and Fixes
- Acknowledgements
- What's New in Python 2.1
- 概述
- PEP 227: Nested Scopes
- PEP 236: future Directives
- PEP 207: Rich Comparisons
- PEP 230: Warning Framework
- PEP 229: New Build System
- PEP 205: Weak References
- PEP 232: Function Attributes
- PEP 235: Importing Modules on Case-Insensitive Platforms
- PEP 217: Interactive Display Hook
- PEP 208: New Coercion Model
- PEP 241: Metadata in Python Packages
- New and Improved Modules
- Other Changes and Fixes
- Acknowledgements
- What's New in Python 2.0
- 概述
- What About Python 1.6?
- New Development Process
- Unicode
- 列表推導式
- Augmented Assignment
- 字符串的方法
- Garbage Collection of Cycles
- Other Core Changes
- Porting to 2.0
- Extending/Embedding Changes
- Distutils: Making Modules Easy to Install
- XML Modules
- Module changes
- New modules
- IDLE Improvements
- Deleted and Deprecated Modules
- Acknowledgements
- 更新日志
- Python 下一版
- Python 3.7.3 最終版
- Python 3.7.3 發布候選版 1
- Python 3.7.2 最終版
- Python 3.7.2 發布候選版 1
- Python 3.7.1 最終版
- Python 3.7.1 RC 2版本
- Python 3.7.1 發布候選版 1
- Python 3.7.0 正式版
- Python 3.7.0 release candidate 1
- Python 3.7.0 beta 5
- Python 3.7.0 beta 4
- Python 3.7.0 beta 3
- Python 3.7.0 beta 2
- Python 3.7.0 beta 1
- Python 3.7.0 alpha 4
- Python 3.7.0 alpha 3
- Python 3.7.0 alpha 2
- Python 3.7.0 alpha 1
- Python 3.6.6 final
- Python 3.6.6 RC 1
- Python 3.6.5 final
- Python 3.6.5 release candidate 1
- Python 3.6.4 final
- Python 3.6.4 release candidate 1
- Python 3.6.3 final
- Python 3.6.3 release candidate 1
- Python 3.6.2 final
- Python 3.6.2 release candidate 2
- Python 3.6.2 release candidate 1
- Python 3.6.1 final
- Python 3.6.1 release candidate 1
- Python 3.6.0 final
- Python 3.6.0 release candidate 2
- Python 3.6.0 release candidate 1
- Python 3.6.0 beta 4
- Python 3.6.0 beta 3
- Python 3.6.0 beta 2
- Python 3.6.0 beta 1
- Python 3.6.0 alpha 4
- Python 3.6.0 alpha 3
- Python 3.6.0 alpha 2
- Python 3.6.0 alpha 1
- Python 3.5.5 final
- Python 3.5.5 release candidate 1
- Python 3.5.4 final
- Python 3.5.4 release candidate 1
- Python 3.5.3 final
- Python 3.5.3 release candidate 1
- Python 3.5.2 final
- Python 3.5.2 release candidate 1
- Python 3.5.1 final
- Python 3.5.1 release candidate 1
- Python 3.5.0 final
- Python 3.5.0 release candidate 4
- Python 3.5.0 release candidate 3
- Python 3.5.0 release candidate 2
- Python 3.5.0 release candidate 1
- Python 3.5.0 beta 4
- Python 3.5.0 beta 3
- Python 3.5.0 beta 2
- Python 3.5.0 beta 1
- Python 3.5.0 alpha 4
- Python 3.5.0 alpha 3
- Python 3.5.0 alpha 2
- Python 3.5.0 alpha 1
- Python 教程
- 課前甜點
- 使用 Python 解釋器
- 調用解釋器
- 解釋器的運行環境
- Python 的非正式介紹
- Python 作為計算器使用
- 走向編程的第一步
- 其他流程控制工具
- if 語句
- for 語句
- range() 函數
- break 和 continue 語句,以及循環中的 else 子句
- pass 語句
- 定義函數
- 函數定義的更多形式
- 小插曲:編碼風格
- 數據結構
- 列表的更多特性
- del 語句
- 元組和序列
- 集合
- 字典
- 循環的技巧
- 深入條件控制
- 序列和其它類型的比較
- 模塊
- 有關模塊的更多信息
- 標準模塊
- dir() 函數
- 包
- 輸入輸出
- 更漂亮的輸出格式
- 讀寫文件
- 錯誤和異常
- 語法錯誤
- 異常
- 處理異常
- 拋出異常
- 用戶自定義異常
- 定義清理操作
- 預定義的清理操作
- 類
- 名稱和對象
- Python 作用域和命名空間
- 初探類
- 補充說明
- 繼承
- 私有變量
- 雜項說明
- 迭代器
- 生成器
- 生成器表達式
- 標準庫簡介
- 操作系統接口
- 文件通配符
- 命令行參數
- 錯誤輸出重定向和程序終止
- 字符串模式匹配
- 數學
- 互聯網訪問
- 日期和時間
- 數據壓縮
- 性能測量
- 質量控制
- 自帶電池
- 標準庫簡介 —— 第二部分
- 格式化輸出
- 模板
- 使用二進制數據記錄格式
- 多線程
- 日志
- 弱引用
- 用于操作列表的工具
- 十進制浮點運算
- 虛擬環境和包
- 概述
- 創建虛擬環境
- 使用pip管理包
- 接下來?
- 交互式編輯和編輯歷史
- Tab 補全和編輯歷史
- 默認交互式解釋器的替代品
- 浮點算術:爭議和限制
- 表示性錯誤
- 附錄
- 交互模式
- 安裝和使用 Python
- 命令行與環境
- 命令行
- 環境變量
- 在Unix平臺中使用Python
- 獲取最新版本的Python
- 構建Python
- 與Python相關的路徑和文件
- 雜項
- 編輯器和集成開發環境
- 在Windows上使用 Python
- 完整安裝程序
- Microsoft Store包
- nuget.org 安裝包
- 可嵌入的包
- 替代捆綁包
- 配置Python
- 適用于Windows的Python啟動器
- 查找模塊
- 附加模塊
- 在Windows上編譯Python
- 其他平臺
- 在蘋果系統上使用 Python
- 獲取和安裝 MacPython
- IDE
- 安裝額外的 Python 包
- Mac 上的圖形界面編程
- 在 Mac 上分發 Python 應用程序
- 其他資源
- Python 語言參考
- 概述
- 其他實現
- 標注
- 詞法分析
- 行結構
- 其他形符
- 標識符和關鍵字
- 字面值
- 運算符
- 分隔符
- 數據模型
- 對象、值與類型
- 標準類型層級結構
- 特殊方法名稱
- 協程
- 執行模型
- 程序的結構
- 命名與綁定
- 異常
- 導入系統
- importlib
- 包
- 搜索
- 加載
- 基于路徑的查找器
- 替換標準導入系統
- Package Relative Imports
- 有關 main 的特殊事項
- 開放問題項
- 參考文獻
- 表達式
- 算術轉換
- 原子
- 原型
- await 表達式
- 冪運算符
- 一元算術和位運算
- 二元算術運算符
- 移位運算
- 二元位運算
- 比較運算
- 布爾運算
- 條件表達式
- lambda 表達式
- 表達式列表
- 求值順序
- 運算符優先級
- 簡單語句
- 表達式語句
- 賦值語句
- assert 語句
- pass 語句
- del 語句
- return 語句
- yield 語句
- raise 語句
- break 語句
- continue 語句
- import 語句
- global 語句
- nonlocal 語句
- 復合語句
- if 語句
- while 語句
- for 語句
- try 語句
- with 語句
- 函數定義
- 類定義
- 協程
- 最高層級組件
- 完整的 Python 程序
- 文件輸入
- 交互式輸入
- 表達式輸入
- 完整的語法規范
- Python 標準庫
- 概述
- 可用性注釋
- 內置函數
- 內置常量
- 由 site 模塊添加的常量
- 內置類型
- 邏輯值檢測
- 布爾運算 — and, or, not
- 比較
- 數字類型 — int, float, complex
- 迭代器類型
- 序列類型 — list, tuple, range
- 文本序列類型 — str
- 二進制序列類型 — bytes, bytearray, memoryview
- 集合類型 — set, frozenset
- 映射類型 — dict
- 上下文管理器類型
- 其他內置類型
- 特殊屬性
- 內置異常
- 基類
- 具體異常
- 警告
- 異常層次結構
- 文本處理服務
- string — 常見的字符串操作
- re — 正則表達式操作
- 模塊 difflib 是一個計算差異的助手
- textwrap — Text wrapping and filling
- unicodedata — Unicode 數據庫
- stringprep — Internet String Preparation
- readline — GNU readline interface
- rlcompleter — GNU readline的完成函數
- 二進制數據服務
- struct — Interpret bytes as packed binary data
- codecs — Codec registry and base classes
- 數據類型
- datetime — 基礎日期/時間數據類型
- calendar — General calendar-related functions
- collections — 容器數據類型
- collections.abc — 容器的抽象基類
- heapq — 堆隊列算法
- bisect — Array bisection algorithm
- array — Efficient arrays of numeric values
- weakref — 弱引用
- types — Dynamic type creation and names for built-in types
- copy — 淺層 (shallow) 和深層 (deep) 復制操作
- pprint — 數據美化輸出
- reprlib — Alternate repr() implementation
- enum — Support for enumerations
- 數字和數學模塊
- numbers — 數字的抽象基類
- math — 數學函數
- cmath — Mathematical functions for complex numbers
- decimal — 十進制定點和浮點運算
- fractions — 分數
- random — 生成偽隨機數
- statistics — Mathematical statistics functions
- 函數式編程模塊
- itertools — 為高效循環而創建迭代器的函數
- functools — 高階函數和可調用對象上的操作
- operator — 標準運算符替代函數
- 文件和目錄訪問
- pathlib — 面向對象的文件系統路徑
- os.path — 常見路徑操作
- fileinput — Iterate over lines from multiple input streams
- stat — Interpreting stat() results
- filecmp — File and Directory Comparisons
- tempfile — Generate temporary files and directories
- glob — Unix style pathname pattern expansion
- fnmatch — Unix filename pattern matching
- linecache — Random access to text lines
- shutil — High-level file operations
- macpath — Mac OS 9 路徑操作函數
- 數據持久化
- pickle —— Python 對象序列化
- copyreg — Register pickle support functions
- shelve — Python object persistence
- marshal — Internal Python object serialization
- dbm — Interfaces to Unix “databases”
- sqlite3 — SQLite 數據庫 DB-API 2.0 接口模塊
- 數據壓縮和存檔
- zlib — 與 gzip 兼容的壓縮
- gzip — 對 gzip 格式的支持
- bz2 — 對 bzip2 壓縮算法的支持
- lzma — 用 LZMA 算法壓縮
- zipfile — 在 ZIP 歸檔中工作
- tarfile — Read and write tar archive files
- 文件格式
- csv — CSV 文件讀寫
- configparser — Configuration file parser
- netrc — netrc file processing
- xdrlib — Encode and decode XDR data
- plistlib — Generate and parse Mac OS X .plist files
- 加密服務
- hashlib — 安全哈希與消息摘要
- hmac — 基于密鑰的消息驗證
- secrets — Generate secure random numbers for managing secrets
- 通用操作系統服務
- os — 操作系統接口模塊
- io — 處理流的核心工具
- time — 時間的訪問和轉換
- argparse — 命令行選項、參數和子命令解析器
- getopt — C-style parser for command line options
- 模塊 logging — Python 的日志記錄工具
- logging.config — 日志記錄配置
- logging.handlers — Logging handlers
- getpass — 便攜式密碼輸入工具
- curses — 終端字符單元顯示的處理
- curses.textpad — Text input widget for curses programs
- curses.ascii — Utilities for ASCII characters
- curses.panel — A panel stack extension for curses
- platform — Access to underlying platform's identifying data
- errno — Standard errno system symbols
- ctypes — Python 的外部函數庫
- 并發執行
- threading — 基于線程的并行
- multiprocessing — 基于進程的并行
- concurrent 包
- concurrent.futures — 啟動并行任務
- subprocess — 子進程管理
- sched — 事件調度器
- queue — 一個同步的隊列類
- _thread — 底層多線程 API
- _dummy_thread — _thread 的替代模塊
- dummy_threading — 可直接替代 threading 模塊。
- contextvars — Context Variables
- Context Variables
- Manual Context Management
- asyncio support
- 網絡和進程間通信
- asyncio — 異步 I/O
- socket — 底層網絡接口
- ssl — TLS/SSL wrapper for socket objects
- select — Waiting for I/O completion
- selectors — 高級 I/O 復用庫
- asyncore — 異步socket處理器
- asynchat — 異步 socket 指令/響應 處理器
- signal — Set handlers for asynchronous events
- mmap — Memory-mapped file support
- 互聯網數據處理
- email — 電子郵件與 MIME 處理包
- json — JSON 編碼和解碼器
- mailcap — Mailcap file handling
- mailbox — Manipulate mailboxes in various formats
- mimetypes — Map filenames to MIME types
- base64 — Base16, Base32, Base64, Base85 數據編碼
- binhex — 對binhex4文件進行編碼和解碼
- binascii — 二進制和 ASCII 碼互轉
- quopri — Encode and decode MIME quoted-printable data
- uu — Encode and decode uuencode files
- 結構化標記處理工具
- html — 超文本標記語言支持
- html.parser — 簡單的 HTML 和 XHTML 解析器
- html.entities — HTML 一般實體的定義
- XML處理模塊
- xml.etree.ElementTree — The ElementTree XML API
- xml.dom — The Document Object Model API
- xml.dom.minidom — Minimal DOM implementation
- xml.dom.pulldom — Support for building partial DOM trees
- xml.sax — Support for SAX2 parsers
- xml.sax.handler — Base classes for SAX handlers
- xml.sax.saxutils — SAX Utilities
- xml.sax.xmlreader — Interface for XML parsers
- xml.parsers.expat — Fast XML parsing using Expat
- 互聯網協議和支持
- webbrowser — 方便的Web瀏覽器控制器
- cgi — Common Gateway Interface support
- cgitb — Traceback manager for CGI scripts
- wsgiref — WSGI Utilities and Reference Implementation
- urllib — URL 處理模塊
- urllib.request — 用于打開 URL 的可擴展庫
- urllib.response — Response classes used by urllib
- urllib.parse — Parse URLs into components
- urllib.error — Exception classes raised by urllib.request
- urllib.robotparser — Parser for robots.txt
- http — HTTP 模塊
- http.client — HTTP協議客戶端
- ftplib — FTP protocol client
- poplib — POP3 protocol client
- imaplib — IMAP4 protocol client
- nntplib — NNTP protocol client
- smtplib —SMTP協議客戶端
- smtpd — SMTP Server
- telnetlib — Telnet client
- uuid — UUID objects according to RFC 4122
- socketserver — A framework for network servers
- http.server — HTTP 服務器
- http.cookies — HTTP state management
- http.cookiejar — Cookie handling for HTTP clients
- xmlrpc — XMLRPC 服務端與客戶端模塊
- xmlrpc.client — XML-RPC client access
- xmlrpc.server — Basic XML-RPC servers
- ipaddress — IPv4/IPv6 manipulation library
- 多媒體服務
- audioop — Manipulate raw audio data
- aifc — Read and write AIFF and AIFC files
- sunau — 讀寫 Sun AU 文件
- wave — 讀寫WAV格式文件
- chunk — Read IFF chunked data
- colorsys — Conversions between color systems
- imghdr — 推測圖像類型
- sndhdr — 推測聲音文件的類型
- ossaudiodev — Access to OSS-compatible audio devices
- 國際化
- gettext — 多語種國際化服務
- locale — 國際化服務
- 程序框架
- turtle — 海龜繪圖
- cmd — 支持面向行的命令解釋器
- shlex — Simple lexical analysis
- Tk圖形用戶界面(GUI)
- tkinter — Tcl/Tk的Python接口
- tkinter.ttk — Tk themed widgets
- tkinter.tix — Extension widgets for Tk
- tkinter.scrolledtext — 滾動文字控件
- IDLE
- 其他圖形用戶界面(GUI)包
- 開發工具
- typing — 類型標注支持
- pydoc — Documentation generator and online help system
- doctest — Test interactive Python examples
- unittest — 單元測試框架
- unittest.mock — mock object library
- unittest.mock 上手指南
- 2to3 - 自動將 Python 2 代碼轉為 Python 3 代碼
- test — Regression tests package for Python
- test.support — Utilities for the Python test suite
- test.support.script_helper — Utilities for the Python execution tests
- 調試和分析
- bdb — Debugger framework
- faulthandler — Dump the Python traceback
- pdb — The Python Debugger
- The Python Profilers
- timeit — 測量小代碼片段的執行時間
- trace — Trace or track Python statement execution
- tracemalloc — Trace memory allocations
- 軟件打包和分發
- distutils — 構建和安裝 Python 模塊
- ensurepip — Bootstrapping the pip installer
- venv — 創建虛擬環境
- zipapp — Manage executable Python zip archives
- Python運行時服務
- sys — 系統相關的參數和函數
- sysconfig — Provide access to Python's configuration information
- builtins — 內建對象
- main — 頂層腳本環境
- warnings — Warning control
- dataclasses — 數據類
- contextlib — Utilities for with-statement contexts
- abc — 抽象基類
- atexit — 退出處理器
- traceback — Print or retrieve a stack traceback
- future — Future 語句定義
- gc — 垃圾回收器接口
- inspect — 檢查對象
- site — Site-specific configuration hook
- 自定義 Python 解釋器
- code — Interpreter base classes
- codeop — Compile Python code
- 導入模塊
- zipimport — Import modules from Zip archives
- pkgutil — Package extension utility
- modulefinder — 查找腳本使用的模塊
- runpy — Locating and executing Python modules
- importlib — The implementation of import
- Python 語言服務
- parser — Access Python parse trees
- ast — 抽象語法樹
- symtable — Access to the compiler's symbol tables
- symbol — 與 Python 解析樹一起使用的常量
- token — 與Python解析樹一起使用的常量
- keyword — 檢驗Python關鍵字
- tokenize — Tokenizer for Python source
- tabnanny — 模糊縮進檢測
- pyclbr — Python class browser support
- py_compile — Compile Python source files
- compileall — Byte-compile Python libraries
- dis — Python 字節碼反匯編器
- pickletools — Tools for pickle developers
- 雜項服務
- formatter — Generic output formatting
- Windows系統相關模塊
- msilib — Read and write Microsoft Installer files
- msvcrt — Useful routines from the MS VC++ runtime
- winreg — Windows 注冊表訪問
- winsound — Sound-playing interface for Windows
- Unix 專有服務
- posix — The most common POSIX system calls
- pwd — 用戶密碼數據庫
- spwd — The shadow password database
- grp — The group database
- crypt — Function to check Unix passwords
- termios — POSIX style tty control
- tty — 終端控制功能
- pty — Pseudo-terminal utilities
- fcntl — The fcntl and ioctl system calls
- pipes — Interface to shell pipelines
- resource — Resource usage information
- nis — Interface to Sun's NIS (Yellow Pages)
- Unix syslog 庫例程
- 被取代的模塊
- optparse — Parser for command line options
- imp — Access the import internals
- 未創建文檔的模塊
- 平臺特定模塊
- 擴展和嵌入 Python 解釋器
- 推薦的第三方工具
- 不使用第三方工具創建擴展
- 使用 C 或 C++ 擴展 Python
- 自定義擴展類型:教程
- 定義擴展類型:已分類主題
- 構建C/C++擴展
- 在Windows平臺編譯C和C++擴展
- 在更大的應用程序中嵌入 CPython 運行時
- Embedding Python in Another Application
- Python/C API 參考手冊
- 概述
- 代碼標準
- 包含文件
- 有用的宏
- 對象、類型和引用計數
- 異常
- 嵌入Python
- 調試構建
- 穩定的應用程序二進制接口
- The Very High Level Layer
- Reference Counting
- 異常處理
- Printing and clearing
- 拋出異常
- Issuing warnings
- Querying the error indicator
- Signal Handling
- Exception Classes
- Exception Objects
- Unicode Exception Objects
- Recursion Control
- 標準異常
- 標準警告類別
- 工具
- 操作系統實用程序
- 系統功能
- 過程控制
- 導入模塊
- Data marshalling support
- 語句解釋及變量編譯
- 字符串轉換與格式化
- 反射
- 編解碼器注冊與支持功能
- 抽象對象層
- Object Protocol
- 數字協議
- Sequence Protocol
- Mapping Protocol
- 迭代器協議
- 緩沖協議
- Old Buffer Protocol
- 具體的對象層
- 基本對象
- 數值對象
- 序列對象
- 容器對象
- 函數對象
- 其他對象
- Initialization, Finalization, and Threads
- 在Python初始化之前
- 全局配置變量
- Initializing and finalizing the interpreter
- Process-wide parameters
- Thread State and the Global Interpreter Lock
- Sub-interpreter support
- Asynchronous Notifications
- Profiling and Tracing
- Advanced Debugger Support
- Thread Local Storage Support
- 內存管理
- 概述
- 原始內存接口
- Memory Interface
- 對象分配器
- 默認內存分配器
- Customize Memory Allocators
- The pymalloc allocator
- tracemalloc C API
- 示例
- 對象實現支持
- 在堆中分配對象
- Common Object Structures
- Type 對象
- Number Object Structures
- Mapping Object Structures
- Sequence Object Structures
- Buffer Object Structures
- Async Object Structures
- 使對象類型支持循環垃圾回收
- API 和 ABI 版本管理
- 分發 Python 模塊
- 關鍵術語
- 開源許可與協作
- 安裝工具
- 閱讀指南
- 我該如何...?
- ...為我的項目選擇一個名字?
- ...創建和分發二進制擴展?
- 安裝 Python 模塊
- 關鍵術語
- 基本使用
- 我應如何 ...?
- ... 在 Python 3.4 之前的 Python 版本中安裝 pip ?
- ... 只為當前用戶安裝軟件包?
- ... 安裝科學計算類 Python 軟件包?
- ... 使用并行安裝的多個 Python 版本?
- 常見的安裝問題
- 在 Linux 的系統 Python 版本上安裝
- 未安裝 pip
- 安裝二進制編譯擴展
- Python 常用指引
- 將 Python 2 代碼遷移到 Python 3
- 簡要說明
- 詳情
- 將擴展模塊移植到 Python 3
- 條件編譯
- 對象API的更改
- 模塊初始化和狀態
- CObject 替換為 Capsule
- 其他選項
- Curses Programming with Python
- What is curses?
- Starting and ending a curses application
- Windows and Pads
- Displaying Text
- User Input
- For More Information
- 實現描述器
- 摘要
- 定義和簡介
- 描述器協議
- 發起調用描述符
- 描述符示例
- Properties
- 函數和方法
- Static Methods and Class Methods
- 函數式編程指引
- 概述
- 迭代器
- 生成器表達式和列表推導式
- 生成器
- 內置函數
- itertools 模塊
- The functools module
- Small functions and the lambda expression
- Revision History and Acknowledgements
- 引用文獻
- 日志 HOWTO
- 日志基礎教程
- 進階日志教程
- 日志級別
- 有用的處理程序
- 記錄日志中引發的異常
- 使用任意對象作為消息
- 優化
- 日志操作手冊
- 在多個模塊中使用日志
- 在多線程中使用日志
- 使用多個日志處理器和多種格式化
- 在多個地方記錄日志
- 日志服務器配置示例
- 處理日志處理器的阻塞
- Sending and receiving logging events across a network
- Adding contextual information to your logging output
- Logging to a single file from multiple processes
- Using file rotation
- Use of alternative formatting styles
- Customizing LogRecord
- Subclassing QueueHandler - a ZeroMQ example
- Subclassing QueueListener - a ZeroMQ example
- An example dictionary-based configuration
- Using a rotator and namer to customize log rotation processing
- A more elaborate multiprocessing example
- Inserting a BOM into messages sent to a SysLogHandler
- Implementing structured logging
- Customizing handlers with dictConfig()
- Using particular formatting styles throughout your application
- Configuring filters with dictConfig()
- Customized exception formatting
- Speaking logging messages
- Buffering logging messages and outputting them conditionally
- Formatting times using UTC (GMT) via configuration
- Using a context manager for selective logging
- 正則表達式HOWTO
- 概述
- 簡單模式
- 使用正則表達式
- 更多模式能力
- 修改字符串
- 常見問題
- 反饋
- 套接字編程指南
- 套接字
- 創建套接字
- 使用一個套接字
- 斷開連接
- 非阻塞的套接字
- 排序指南
- 基本排序
- 關鍵函數
- Operator 模塊函數
- 升序和降序
- 排序穩定性和排序復雜度
- 使用裝飾-排序-去裝飾的舊方法
- 使用 cmp 參數的舊方法
- 其它
- Unicode 指南
- Unicode 概述
- Python's Unicode Support
- Reading and Writing Unicode Data
- Acknowledgements
- 如何使用urllib包獲取網絡資源
- 概述
- Fetching URLs
- 處理異常
- info and geturl
- Openers and Handlers
- Basic Authentication
- Proxies
- Sockets and Layers
- 腳注
- Argparse 教程
- 概念
- 基礎
- 位置參數介紹
- Introducing Optional arguments
- Combining Positional and Optional arguments
- Getting a little more advanced
- Conclusion
- ipaddress模塊介紹
- 創建 Address/Network/Interface 對象
- 審查 Address/Network/Interface 對象
- Network 作為 Address 列表
- 比較
- 將IP地址與其他模塊一起使用
- 實例創建失敗時獲取更多詳細信息
- Argument Clinic How-To
- The Goals Of Argument Clinic
- Basic Concepts And Usage
- Converting Your First Function
- Advanced Topics
- 使用 DTrace 和 SystemTap 檢測CPython
- Enabling the static markers
- Static DTrace probes
- Static SystemTap markers
- Available static markers
- SystemTap Tapsets
- 示例
- Python 常見問題
- Python常見問題
- 一般信息
- 現實世界中的 Python
- 編程常見問題
- 一般問題
- 核心語言
- 數字和字符串
- 性能
- 序列(元組/列表)
- 對象
- 模塊
- 設計和歷史常見問題
- 為什么Python使用縮進來分組語句?
- 為什么簡單的算術運算得到奇怪的結果?
- 為什么浮點計算不準確?
- 為什么Python字符串是不可變的?
- 為什么必須在方法定義和調用中顯式使用“self”?
- 為什么不能在表達式中賦值?
- 為什么Python對某些功能(例如list.index())使用方法來實現,而其他功能(例如len(List))使用函數實現?
- 為什么 join()是一個字符串方法而不是列表或元組方法?
- 異常有多快?
- 為什么Python中沒有switch或case語句?
- 難道不能在解釋器中模擬線程,而非得依賴特定于操作系統的線程實現嗎?
- 為什么lambda表達式不能包含語句?
- 可以將Python編譯為機器代碼,C或其他語言嗎?
- Python如何管理內存?
- 為什么CPython不使用更傳統的垃圾回收方案?
- CPython退出時為什么不釋放所有內存?
- 為什么有單獨的元組和列表數據類型?
- 列表是如何在CPython中實現的?
- 字典是如何在CPython中實現的?
- 為什么字典key必須是不可變的?
- 為什么 list.sort() 沒有返回排序列表?
- 如何在Python中指定和實施接口規范?
- 為什么沒有goto?
- 為什么原始字符串(r-strings)不能以反斜杠結尾?
- 為什么Python沒有屬性賦值的“with”語句?
- 為什么 if/while/def/class語句需要冒號?
- 為什么Python在列表和元組的末尾允許使用逗號?
- 代碼庫和插件 FAQ
- 通用的代碼庫問題
- 通用任務
- 線程相關
- 輸入輸出
- 網絡 / Internet 編程
- 數據庫
- 數學和數字
- 擴展/嵌入常見問題
- 可以使用C語言中創建自己的函數嗎?
- 可以使用C++語言中創建自己的函數嗎?
- C很難寫,有沒有其他選擇?
- 如何從C執行任意Python語句?
- 如何從C中評估任意Python表達式?
- 如何從Python對象中提取C的值?
- 如何使用Py_BuildValue()創建任意長度的元組?
- 如何從C調用對象的方法?
- 如何捕獲PyErr_Print()(或打印到stdout / stderr的任何內容)的輸出?
- 如何從C訪問用Python編寫的模塊?
- 如何從Python接口到C ++對象?
- 我使用Setup文件添加了一個模塊,為什么make失敗了?
- 如何調試擴展?
- 我想在Linux系統上編譯一個Python模塊,但是缺少一些文件。為什么?
- 如何區分“輸入不完整”和“輸入無效”?
- 如何找到未定義的g++符號__builtin_new或__pure_virtual?
- 能否創建一個對象類,其中部分方法在C中實現,而其他方法在Python中實現(例如通過繼承)?
- Python在Windows上的常見問題
- 我怎樣在Windows下運行一個Python程序?
- 我怎么讓 Python 腳本可執行?
- 為什么有時候 Python 程序會啟動緩慢?
- 我怎樣使用Python腳本制作可執行文件?
- *.pyd 文件和DLL文件相同嗎?
- 我怎樣將Python嵌入一個Windows程序?
- 如何讓編輯器不要在我的 Python 源代碼中插入 tab ?
- 如何在不阻塞的情況下檢查按鍵?
- 圖形用戶界面(GUI)常見問題
- 圖形界面常見問題
- Python 是否有平臺無關的圖形界面工具包?
- 有哪些Python的GUI工具是某個平臺專用的?
- 有關Tkinter的問題
- “為什么我的電腦上安裝了 Python ?”
- 什么是Python?
- 為什么我的電腦上安裝了 Python ?
- 我能刪除 Python 嗎?
- 術語對照表
- 文檔說明
- Python 文檔貢獻者
- 解決 Bug
- 文檔錯誤
- 使用 Python 的錯誤追蹤系統
- 開始為 Python 貢獻您的知識
- 版權
- 歷史和許可證
- 軟件歷史
- 訪問Python或以其他方式使用Python的條款和條件
- Python 3.7.3 的 PSF 許可協議
- Python 2.0 的 BeOpen.com 許可協議
- Python 1.6.1 的 CNRI 許可協議
- Python 0.9.0 至 1.2 的 CWI 許可協議
- 集成軟件的許可和認可
- Mersenne Twister
- 套接字
- Asynchronous socket services
- Cookie management
- Execution tracing
- UUencode and UUdecode functions
- XML Remote Procedure Calls
- test_epoll
- Select kqueue
- SipHash24
- strtod and dtoa
- OpenSSL
- expat
- libffi
- zlib
- cfuhash
- libmpdec