內建型別

以下各節介紹瞭解釋器內建的標準型別。

主要的內建型別是數字、序列、對映、類、例項和異常。

某些集合類是可變的。那些原地新增、移除或重排成員且不返回特定項的方法,永遠不會返回集合例項本身,而是返回 None

許多物件型別支援某些操作;特別是,幾乎所有物件都可以進行相等性比較、真值測試,並轉換為字串(透過 repr() 函式或略有不同的 str() 函式)。後者在物件被 print() 函式寫入時隱式使用。

真值測試

任何物件都可以進行真值測試,以用於 ifwhile 條件中,或作為以下布林運算的運算元。

預設情況下,一個物件被認為是真的,除非它的類定義了一個返回 False__bool__() 方法,或者一個返回零的 __len__() 方法(當用該物件呼叫時)。[1] 以下是大多數被認為是假的內建物件

  • 定義為假的常量:NoneFalse

  • 任何數字型別的零:0, 0.0, 0j, Decimal(0), Fraction(0, 1)

  • 空序列和空集合:'', (), [], {}, set(), range(0)

具有布林結果的操作和內建函式總是返回 0False 表示假,返回 1True 表示真,除非另有說明。(重要例外:布林操作 orand 總是返回其運算元之一。)

布林運算 — and, or, not

這些是布林運算,按優先順序升序列出

操作

結果

備註

x or y

如果 *x* 為真,則返回 *x*,否則返回 *y*

(1)

x and y

如果 *x* 為假,則返回 *x*,否則返回 *y*

(2)

not x

如果 *x* 為假,則返回 True,否則返回 False

(3)

備註

  1. 這是一個短路運算子,因此僅當第一個引數為假時才對其第二個引數進行求值。

  2. 這是一個短路運算子,因此僅當第一個引數為真時才對其第二個引數進行求值。

  3. not 的優先順序低於非布林運算子,因此 not a == b 被解釋為 not (a == b),而 a == not b 是語法錯誤。

比較操作

Python 中有八種比較運算。它們都具有相同的優先順序(高於布林運算的優先順序)。比較可以任意連結;例如,x < y <= z 等價於 x < y and y <= z,除了 *y* 只被求值一次(但在兩種情況下,如果 x < y 被發現為假,則 *z* 根本不被求值)。

下表總結了比較運算

操作

含義

<

嚴格小於

<=

小於或等於

>

嚴格大於

>=

大於或等於

==

等於

!=

不等於

is

物件標識

is not

否定的物件標識

不同型別的物件(不同數值型別除外)永遠不相等。 == 運算子始終已定義,但對於某些物件型別(例如類物件)它等同於 is<, <=, >>= 運算子僅在它們有意義時定義;例如,當其中一個引數是複數時,它們會引發 TypeError 異常。

一個類的不同例項通常比較為不相等,除非該類定義了 __eq__() 方法。

類的例項不能相對於同一類的其他例項或其他型別的物件進行排序,除非該類定義了足夠多的方法 __lt__(), __le__(), __gt__(), 和 __ge__() (通常,如果你想要比較運算子的常規含義,__lt__()__eq__() 就足夠了)。

isis not 運算子的行為無法自定義;此外,它們可以應用於任何兩個物件,並且永遠不會引發異常。

另外兩個具有相同語法優先順序的操作 innot in,由 可迭代 的型別或實現了 __contains__() 方法的型別支援。

數字型別 — int, float, complex

有三種不同的數字型別:整數浮點數,和複數。此外,布林值是整數的一個子型別。整數具有無限精度。浮點數通常使用 C 中的 double 實現;有關機器上浮點數的精度和內部表示的資訊,請參閱 sys.float_info。複數具有實部和虛部,它們都是浮點數。要從複數 *z* 中提取這些部分,請使用 z.realz.imag。(標準庫包含額外的數字型別 fractions.Fraction (用於有理數) 和 decimal.Decimal (用於使用者可定義精度的浮點數)。)

數字可以透過數字字面量建立,或者作為內建函式和運算子的結果建立。無裝飾的整數字面量(包括十六進位制、八進位制和二進位制數字)產生整數。包含小數點或指數符號的數字字面量產生浮點數。在數字字面量後附加 'j''J' 會產生一個虛數(實部為零的複數),您可以將其加到一個整數或浮點數上以得到一個具有實部和虛部的複數。

建構函式 int(), float(), 和 complex() 可用於生成特定型別的數字。

Python 完全支援混合算術:當一個二元算術運算子的兩個運算元是不同數字型別時,較“窄”型別的運算元會被提升為與另一個運算元相同的型別,其中整數比浮點數窄。複數與實數算術按照常規數學公式定義,例如

x + complex(u, v) = complex(x + u, v)
x * complex(u, v) = complex(x * u, x * v)

不同型別數字之間的比較,就好像在比較這些數字的精確值一樣。[2]

所有數字型別(複數除外)都支援以下操作(有關操作優先順序,請參閱 運算子優先順序

操作

結果

備註

完整文件

x + y

*x* 和 *y* 的和

x - y

*x* 和 *y* 的差

x * y

*x* 和 *y* 的積

x / y

*x* 除以 *y* 的商

x // y

*x* 除以 *y* 的地板商

(1)(2)

x % y

*x* / *y* 的餘數

(2)

-x

*x* 的負值

+x

*x* 不變

abs(x)

*x* 的絕對值或大小

abs()

int(x)

*x* 轉換為整數

(3)(6)

int()

float(x)

*x* 轉換為浮點數

(4)(6)

float()

complex(re, im)

一個複數,實部為 *re*,虛部為 *im*。*im* 預設為零。

(6)

complex()

c.conjugate()

複數 *c* 的共軛

divmod(x, y)

(x // y, x % y) 的對

(2)

divmod()

pow(x, y)

*x* 的 *y* 次冪

(5)

pow()

x ** y

*x* 的 *y* 次冪

(5)

備註

  1. 也稱為整數除法。對於 int 型別的運算元,結果型別為 int。對於 float 型別的運算元,結果型別為 float。總的來說,結果是一個整數,儘管結果的型別不一定是 int。結果總是向負無窮方向舍入:1//20(-1)//2-11//(-2)-1,而 (-1)//(-2)0

  2. 不適用於複數。如果需要,請改用 abs() 轉換為浮點數。

  3. floatint 的轉換會截斷,丟棄小數部分。有關替代轉換,請參閱 math.floor()math.ceil() 函式。

  4. float 還接受字串“nan”和“inf”,以及可選的字首“+”或“-”,分別表示非數字 (NaN) 和正負無窮大。

  5. Python 將 pow(0, 0)0 ** 0 定義為 1,這與許多程式語言的習慣相同。

  6. 接受的數字字面量包括數字 09 或任何 Unicode 等效字元(具有 Nd 屬性的程式碼點)。

    有關 Nd 屬性的程式碼點列表,請參閱 Unicode 標準

所有 numbers.Real 型別(intfloat)還包括以下操作

操作

結果

math.trunc(x)

*x* 截斷為 Integral

round(x[, n])

*x* 四捨五入到 *n* 位,採用四捨五入到偶數。如果省略 *n*,則預設為 0。

math.floor(x)

小於或等於 *x* 的最大 Integral

math.ceil(x)

大於或等於 *x* 的最小 Integral

有關更多數字運算,請參閱 mathcmath 模組。

整數型別的按位運算

按位運算只對整數有意義。按位運算的結果被計算為好像是在具有無限符號位的二進位制補碼中進行的。

二元按位運算的優先順序都低於算術運算,高於比較運算;一元運算 ~ 具有與其他一元算術運算(+-)相同的優先順序。

下表列出了按位運算,按優先順序升序列出

操作

結果

備註

x | y

*x* 和 *y* 的按位 *或*

(4)

x ^ y

*x* 和 *y* 的按位 *異或*

(4)

x & y

*x* 和 *y* 的按位 *與*

(4)

x << n

*x* 左移 *n* 位

(1)(2)

x >> n

*x* 右移 *n* 位

(1)(3)

~x

*x* 的位反轉

備註

  1. 負移位計數是非法的,會導致引發 ValueError

  2. 左移 *n* 位等同於乘以 pow(2, n)

  3. 右移 *n* 位等同於地板除以 pow(2, n)

  4. 使用至少一個額外的符號擴充套件位在有限二進位制補碼錶示中(工作位寬度為 1 + max(x.bit_length(), y.bit_length()) 或更大)執行這些計算足以獲得與無限個符號位相同的結果。

整數型別的附加方法

int 型別實現了 numbers.Integral 抽象基類。此外,它還提供了一些其他方法

int.bit_length()

返回表示整數的二進位制位的數量,不包括符號和前導零

>>> n = -37
>>> bin(n)
'-0b100101'
>>> n.bit_length()
6

更準確地說,如果 x 非零,則 x.bit_length() 是唯一的正整數 k,使得 2**(k-1) <= abs(x) < 2**k。等效地,當 abs(x) 足夠小時,可以正確舍入其對數,則 k = 1 + int(log(abs(x), 2))。如果 x 為零,則 x.bit_length() 返回 0

等價於:

def bit_length(self):
    s = bin(self)       # binary representation:  bin(-37) --> '-0b100101'
    s = s.lstrip('-0b') # remove leading zeros and minus sign
    return len(s)       # len('100101') --> 6

在 3.1 版本加入。

int.bit_count()

返回整數絕對值的二進位制表示中“1”的數量。這也被稱為人口計數。例如

>>> n = 19
>>> bin(n)
'0b10011'
>>> n.bit_count()
3
>>> (-n).bit_count()
3

等價於:

def bit_count(self):
    return bin(self).count("1")

在 3.10 版本加入。

int.to_bytes(length=1, byteorder='big', *, signed=False)

返回表示整數的位元組陣列。

>>> (1024).to_bytes(2, byteorder='big')
b'\x04\x00'
>>> (1024).to_bytes(10, byteorder='big')
b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00'
>>> (-1024).to_bytes(10, byteorder='big', signed=True)
b'\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x00'
>>> x = 1000
>>> x.to_bytes((x.bit_length() + 7) // 8, byteorder='little')
b'\xe8\x03'

整數用 *length* 位元組表示,預設為 1。如果整數無法用給定的位元組數表示,則會引發 OverflowError

*byteorder* 引數確定用於表示整數的位元組順序,預設為 "big"。如果 *byteorder* 是 "big",則最高有效位元組位於位元組陣列的開頭。如果 *byteorder* 是 "little",則最高有效位元組位於位元組陣列的末尾。

*signed* 引數確定是否使用二進位制補碼錶示整數。如果 *signed* 為 False 且給出負整數,則會引發 OverflowError。*signed* 的預設值為 False

預設引數可以方便地將整數轉換為單個位元組物件

>>> (65).to_bytes()
b'A'

但是,在使用預設引數時,不要嘗試轉換大於 255 的值,否則會收到 OverflowError

等價於:

def to_bytes(n, length=1, byteorder='big', signed=False):
    if byteorder == 'little':
        order = range(length)
    elif byteorder == 'big':
        order = reversed(range(length))
    else:
        raise ValueError("byteorder must be either 'little' or 'big'")

    return bytes((n >> i*8) & 0xff for i in order)

在 3.2 版本加入。

已在版本 3.11 中更改: lengthbyteorder 添加了預設引數值。

classmethod int.from_bytes(bytes, byteorder='big', *, signed=False)

返回由給定位元組陣列表示的整數。

>>> int.from_bytes(b'\x00\x10', byteorder='big')
16
>>> int.from_bytes(b'\x00\x10', byteorder='little')
4096
>>> int.from_bytes(b'\xfc\x00', byteorder='big', signed=True)
-1024
>>> int.from_bytes(b'\xfc\x00', byteorder='big', signed=False)
64512
>>> int.from_bytes([255, 0, 0], byteorder='big')
16711680

引數 *bytes* 必須是 位元組類物件 或生成位元組的可迭代物件。

*byteorder* 引數確定用於表示整數的位元組順序,預設為 "big"。如果 *byteorder* 是 "big",則最高有效位元組位於位元組陣列的開頭。如果 *byteorder* 是 "little",則最高有效位元組位於位元組陣列的末尾。要請求主機系統的本機位元組順序,請使用 sys.byteorder 作為位元組順序值。

*signed* 引數指示是否使用二進位制補碼錶示整數。

等價於:

def from_bytes(bytes, byteorder='big', signed=False):
    if byteorder == 'little':
        little_ordered = list(bytes)
    elif byteorder == 'big':
        little_ordered = list(reversed(bytes))
    else:
        raise ValueError("byteorder must be either 'little' or 'big'")

    n = sum(b << i*8 for i, b in enumerate(little_ordered))
    if signed and little_ordered and (little_ordered[-1] & 0x80):
        n -= 1 << 8*len(little_ordered)

    return n

在 3.2 版本加入。

已在版本 3.11 中更改: byteorder 添加了預設引數值。

int.as_integer_ratio()

返回一個整數對,其比率等於原始整數,並且分母為正。整數(整數)的整數比始終是整數作為分子,1 作為分母。

在 3.8 版本加入。

int.is_integer()

返回 True。為與 float.is_integer() 的鴨子型別相容而存在。

3.12 新版功能.

浮點數的附加方法

float 型別實現了 numbers.Real 抽象基類。float 還具有以下附加方法。

classmethod float.from_number(x)

類方法,用於從數字 *x* 返回一個浮點數。

如果引數是整數或浮點數,則返回具有相同值(在 Python 的浮點精度範圍內)的浮點數。如果引數超出 Python 浮點數的範圍,將引發 OverflowError

對於通用 Python 物件 xfloat.from_number(x) 呼叫 x.__float__()。如果未定義 __float__(),則回退到 __index__()

在 3.14 版本加入。

float.as_integer_ratio()

返回一個整數對,其比率恰好等於原始浮點數。該比率是不可約的,分母為正。對於無窮大,引發 OverflowError,對於 NaN,引發 ValueError

float.is_integer()

當浮點例項是有限的且值為整數時返回 True,否則返回 False

>>> (-2.0).is_integer()
True
>>> (3.2).is_integer()
False

兩種方法支援與十六進位制字串的轉換。由於 Python 的浮點數在內部儲存為二進位制數,因此將浮點數轉換為或從十進位制字串轉換通常會涉及小的舍入誤差。相比之下,十六進位制字串允許對浮點數進行精確表示和指定。這在除錯時以及在數值工作中可能很有用。

float.hex()

返回浮點數的十六進位制字串表示。對於有限浮點數,此表示始終包含前導 0x 和尾隨的 p 和指數。

classmethod float.fromhex(s)

類方法,用於返回由十六進位制字串 *s* 表示的浮點數。字串 *s* 可能包含前導和尾隨空格。

請注意,float.hex() 是一個例項方法,而 float.fromhex() 是一個類方法。

十六進位制字串的形式為

[sign] ['0x'] integer ['.' fraction] ['p' exponent]

其中可選的 sign 可以是 +-integerfraction 是十六進位制數字字串,而 exponent 是帶可選符號的十進位制整數。大小寫不敏感,整數或分數中必須至少有一個十六進位制數字。此語法類似於 C99 標準第 6.4.4.2 節中指定的語法,也類似於 Java 1.5 及更高版本中使用的語法。特別是,float.hex() 的輸出可以用作 C 或 Java 程式碼中的十六進位制浮點文字,並且 C 的 %a 格式字元或 Java 的 Double.toHexString 產生的十六進位制字串被 float.fromhex() 接受。

請注意,指數以十進位制而不是十六進位制書寫,它表示用於乘以係數的 2 的冪。例如,十六進位制字串 0x3.a7p10 表示浮點數 (3 + 10./16 + 7./16**2) * 2.0**10,即 3740.0

>>> float.fromhex('0x3.a7p10')
3740.0

將反向轉換應用於 3740.0 會得到一個表示相同數字的不同十六進位制字串

>>> float.hex(3740.0)
'0x1.d380000000000p+11'

複數的附加方法

complex 型別實現了 numbers.Complex 抽象基類complex 還具有以下附加方法。

classmethod complex.from_number(x)

類方法,用於將數字轉換為複數。

對於通用 Python 物件 xcomplex.from_number(x) 呼叫 x.__complex__()。如果未定義 __complex__(),則回退到 __float__()。如果未定義 __float__(),則回退到 __index__()

在 3.14 版本加入。

數字型別的雜湊

對於數字 xy,可能型別不同,一個要求是 hash(x) == hash(y) 當且僅當 x == y(有關更多詳細資訊,請參閱 __hash__() 方法文件)。為了在各種數字型別(包括 int, float, decimal.Decimalfractions.Fraction)之間易於實現和高效,Python 對數字型別的雜湊基於一個單一的數學函式,該函式對任何有理數都已定義,因此適用於 intfractions.Fraction 的所有例項,以及 floatdecimal.Decimal 的所有有限例項。本質上,該函式由模 P 約簡給出,其中 P 是一個固定的素數。 P 的值可透過 Python 的 modulus 屬性(位於 sys.hash_info 中)訪問。

CPython 實現細節: 當前,在 32 位 C long 的機器上使用的素數是 P = 2**31 - 1,在 64 位 C long 的機器上使用的素數是 P = 2**61 - 1

以下是詳細規則

  • 如果 x = m / n 是一個非負有理數,並且 n 不能被 P 整除,則定義 hash(x)m * invmod(n, P) % P,其中 invmod(n, P)nP 的逆。

  • 如果 x = m / n 是一個非負有理數,並且 n 能被 P 整除(但 *m* 不能),那麼 n 在模 P 下沒有逆,並且上述規則不適用;在這種情況下,將 hash(x) 定義為常量值 sys.hash_info.inf

  • 如果 x = m / n 是一個負有理數,則定義 hash(x)-hash(-x)。如果結果雜湊值為 -1,則將其替換為 -2

  • 特定的值 sys.hash_info.inf-sys.hash_info.inf 分別用作正無窮大或負無窮大的雜湊值。

  • 對於 complex 數 *z*,其實部和虛部的雜湊值透過計算 hash(z.real) + sys.hash_info.imag * hash(z.imag) 來組合,然後模 2**sys.hash_info.width 約簡,使其位於 range(-2**(sys.hash_info.width - 1), 2**(sys.hash_info.width - 1))。同樣,如果結果是 -1,則將其替換為 -2

為了闡明上述規則,這裡提供了一些等同於內建雜湊的示例 Python 程式碼,用於計算有理數、floatcomplex 的雜湊值

import sys, math

def hash_fraction(m, n):
    """Compute the hash of a rational number m / n.

    Assumes m and n are integers, with n positive.
    Equivalent to hash(fractions.Fraction(m, n)).

    """
    P = sys.hash_info.modulus
    # Remove common factors of P.  (Unnecessary if m and n already coprime.)
    while m % P == n % P == 0:
        m, n = m // P, n // P

    if n % P == 0:
        hash_value = sys.hash_info.inf
    else:
        # Fermat's Little Theorem: pow(n, P-1, P) is 1, so
        # pow(n, P-2, P) gives the inverse of n modulo P.
        hash_value = (abs(m) % P) * pow(n, P - 2, P) % P
    if m < 0:
        hash_value = -hash_value
    if hash_value == -1:
        hash_value = -2
    return hash_value

def hash_float(x):
    """Compute the hash of a float x."""

    if math.isnan(x):
        return object.__hash__(x)
    elif math.isinf(x):
        return sys.hash_info.inf if x > 0 else -sys.hash_info.inf
    else:
        return hash_fraction(*x.as_integer_ratio())

def hash_complex(z):
    """Compute the hash of a complex number z."""

    hash_value = hash_float(z.real) + sys.hash_info.imag * hash_float(z.imag)
    # do a signed reduction modulo 2**sys.hash_info.width
    M = 2**(sys.hash_info.width - 1)
    hash_value = (hash_value & (M - 1)) - (hash_value & M)
    if hash_value == -1:
        hash_value = -2
    return hash_value

布林型別 - bool

布林值表示真值。 bool 型別恰好有兩個常量例項:TrueFalse

內建函式 bool() 將任何值轉換為布林值,前提是該值可以解釋為真值(請參閱上面 真值測試 部分)。

對於邏輯運算,請使用 布林運算子 and, ornot。當對兩個布林值應用按位運算子 &, |, ^ 時,它們返回一個等同於邏輯運算“and”、“or”、“xor”的布林值。然而,邏輯運算子 and, or!= 應優先於 &, |^

已棄用,版本 3.12: 使用按位反轉運算子 ~ 已棄用,將在 Python 3.16 中引發錯誤。

boolint 的子類(請參閱 數字型別 — int, float, complex)。在許多數字上下文中,FalseTrue 分別表現得像整數 0 和 1。但是,依賴這一點是不鼓勵的;最好明確使用 int() 進行轉換。

迭代器型別

Python 支援一種容器迭代的概念。這是透過兩種不同的方法實現的;它們用於允許使用者定義的類支援迭代。序列(將在下面更詳細地描述)始終支援迭代方法。

需要為容器物件定義一種方法來提供 可迭代 支援

container.__iter__()

返回一個 迭代器 物件。該物件需要支援下面描述的迭代器協議。如果容器支援不同型別的迭代,可以提供其他方法來專門請求這些迭代型別的迭代器。(支援多種迭代形式的物件例如是支援廣度優先和深度優先遍歷的樹結構。)此方法對應於 Python/C API 中 Python 物件型別的 tp_iter 插槽。

迭代器物件本身需要支援以下兩個方法,它們共同構成了迭代器協議

iterator.__iter__()

返回 迭代器 物件本身。這對於允許容器和迭代器都用於 forin 語句是必需的。此方法對應於 Python/C API 中 Python 物件型別的 tp_iter 插槽。

iterator.__next__()

迭代器 返回下一個項。如果沒有更多項,則引發 StopIteration 異常。此方法對應於 Python/C API 中 Python 物件型別的 tp_iternext 插槽。

Python 定義了多種迭代器物件來支援通用和特定序列型別、字典以及其他更專門形式的迭代。具體型別並不重要,除非它們實現了迭代器協議。

一旦迭代器的 __next__() 方法引發 StopIteration,它必須在後續呼叫中繼續這樣做。不遵守此屬性的實現被視為有缺陷。

生成器型別

Python 的 生成器 提供了一種實現迭代器協議的便捷方式。如果容器物件的 __iter__() 方法被實現為生成器,它將自動返回一個提供 __iter__()__next__() 方法的迭代器物件(技術上是生成器物件)。有關生成器的更多資訊可以在 yield 表示式文件 中找到。

序列型別 — list, tuple, range

有三種基本序列型別:列表、元組和 range 物件。另外兩種針對二進位制資料文字字串處理量身定製的序列型別在專門的章節中進行了描述。

通用序列操作

下表中列出的操作被大多數序列型別(包括可變和不可變型別)支援。 collections.abc.Sequence ABC 的提供是為了更容易地正確實現這些操作在自定義序列型別上。

下表列出了序列操作,按優先順序升序列出。表中,*s* 和 *t* 是同一型別的序列,*n*, *i*, *j*, 和 *k* 是整數,*x* 是任意物件,它滿足 *s* 施加的任何型別和值限制。

innot in 操作具有與比較運算相同的優先順序。 + (連線) 和 * (重複) 操作具有與相應的算術運算相同的優先順序。[3]

操作

結果

備註

x in s

如果 *s* 的某個項等於 *x*,則為 True,否則為 False

(1)

x not in s

如果 *s* 的某個項等於 *x*,則為 False,否則為 True

(1)

s + t

*s* 和 *t* 的連線

(6)(7)

s * nn * s

等同於將 *s* 與自身相加 *n* 次

(2)(7)

s[i]

*s* 的第 *i* 項,從 0 開始

(3)(8)

s[i:j]

從 *i* 到 *j* 的 *s* 的切片

(3)(4)

s[i:j:k]

從 *i* 到 *j*、步長為 *k* 的 *s* 的切片

(3)(5)

len(s)

*s* 的長度

min(s)

*s* 的最小項

max(s)

*s* 的最大項

相同型別的序列也支援比較。特別是,元組和列表透過比較對應元素來進行詞典式排序。這意味著要相等,每個元素必須相等,並且兩個序列必須是同一型別且長度相同。(有關完整詳細資訊,請參閱語言參考中的 比較。)

對可變序列的正向和反向迭代器透過索引訪問值。即使底層序列被修改,該索引也會繼續向前(或向後)移動。迭代器僅在遇到 IndexErrorStopIteration 時(或當索引降至零以下時)終止。

備註

  1. 雖然 innot in 操作在一般情況下僅用於簡單的包含測試,但一些特殊序列(如 str, bytesbytearray)也使用它們進行子序列測試

    >>> "gg" in "eggs"
    True
    
  2. 小於 0 的 *n* 的值被視為 0(這將產生與 *s* 相同型別的空序列)。請注意,序列 *s* 中的項不會被複制;它們被多次引用。這通常會困擾新手 Python 程式設計師;考慮

    >>> lists = [[]] * 3
    >>> lists
    [[], [], []]
    >>> lists[0].append(3)
    >>> lists
    [[3], [3], [3]]
    

    發生的情況是 [[]] 是一個包含空列表的單元素列表,因此 [[]] * 3 的所有三個元素都是對這個單一空列表的引用。修改 lists 的任何元素都會修改這個單一列表。你可以這樣建立一個包含不同列表的列表

    >>> lists = [[] for i in range(3)]
    >>> lists[0].append(3)
    >>> lists[1].append(5)
    >>> lists[2].append(7)
    >>> lists
    [[3], [5], [7]]
    

    有關進一步的解釋,請參閱 FAQ 條目 如何建立多維列表?

  3. 如果 *i* 或 *j* 為負數,則索引相對於序列 *s* 的末尾:用 len(s) + ilen(s) + j 替換。但請注意 -0 仍然是 0

  4. *i* 到 *j* 的 *s* 切片定義為索引為 *k* 的項的序列,其中 i <= k < j。如果 *i* 或 *j* 大於 len(s),則使用 len(s)。如果 *i* 被省略或為 None,則使用 0。如果 *j* 被省略或為 None,則使用 len(s)。如果 *i* 大於或等於 *j*,則切片為空。

  5. 步長為 *k* 的從 *i* 到 *j* 的 *s* 切片定義為索引為 x = i + n*k 的項的序列,其中 0 <= n < (j-i)/k。換句話說,索引是 i, i+k, i+2*k, i+3*k 等等,直到達到 *j*(但永遠不包括 *j*)。當 *k* 為正數時,如果 *i* 和 *j* 大於 len(s),則將它們減小到 len(s)。當 *k* 為負數時,如果 *i* 和 *j* 大於 len(s) - 1,則將它們減小到 len(s) - 1。如果 *i* 或 *j* 被省略或為 None,它們將變成“結束”值(具體是哪個結束取決於 *k* 的符號)。注意,*k* 不能為零。如果 *k* 為 None,則將其視為 1

  6. 連線不可變序列總是會產生一個新物件。這意味著透過重複連線來構建序列將具有總序列長度的二次執行時間成本。要獲得線性執行時間成本,您必須切換到以下選項之一

    • 如果連線 str 物件,您可以先構建一個列表,然後在最後使用 str.join(),或者寫入一個 io.StringIO 例項,並在完成後檢索其值。

    • 如果連線 bytes 物件,您可以類似地使用 bytes.join()io.BytesIO,或者使用 bytearray 物件進行就地連線。 bytearray 物件是可變的,並且具有有效的預分配機制。

    • 如果連線 tuple 物件,則應改為擴充套件一個 list

    • 對於其他型別,請研究相關的類文件。

  7. 某些序列型別(例如 range)僅支援遵循特定模式的專案序列,因此不支援序列連線或重複。

  8. 如果 i 超出序列範圍,則引發 IndexError

序列方法

序列型別還支援以下方法

sequence.count(value, /)

返回 valuesequence 中出現的總次數。

sequence.index(value[, start[, stop])

返回 valuesequence 中首次出現的索引。

如果 valuesequence 中未找到,則引發 ValueError

startstop 引數允許高效地搜尋序列的子部分,從 start 開始,在 stop 結束。這大致相當於 start + sequence[start:stop].index(value),只是沒有複製任何資料。

注意

並非所有序列型別都支援傳遞 startstop 引數。

不可變序列型別

不可變序列型別通常實現的唯一操作是也由可變序列型別實現的操作,即內建 hash() 的支援。

此支援允許不可變序列(例如 tuple 例項)用作 dict 鍵,並存儲在 setfrozenset 例項中。

嘗試雜湊包含不可雜湊值的不可變序列將導致 TypeError

可變序列型別

下表中的操作定義在可變序列型別上。提供了 collections.abc.MutableSequence ABC,以便更輕鬆地在自定義序列型別上正確實現這些操作。

在表中,s 是可變序列型別的例項,t 是任何可迭代物件,x 是滿足 s 施加的任何型別和值限制的任意物件(例如,bytearray 只接受滿足 0 <= x <= 255 值限制的整數)。

操作

結果

備註

s[i] = x

s 的項 ix 替換

del s[i]

刪除 s 的項 i

s[i:j] = t

ijs 的切片被可迭代物件 t 的內容替換

del s[i:j]

從列表中刪除 s[i:j] 的元素(與 s[i:j] = [] 相同)

s[i:j:k] = t

i:j:ks 的元素被 t 的元素替換

(1)

del s[i:j:k]

刪除列表中 s[i:j:k] 的元素

s += t

t 的內容擴充套件 s(在大多數情況下與 s[len(s):len(s)] = t 相同)

s *= n

用重複 n 次的內容更新 s

(2)

備註

  1. 如果 k 不等於 1,則 t 必須具有與它所替換的切片相同的長度。

  2. n 是整數,或實現了 __index__() 的物件。 n 的零和負值會清空序列。序列中的項不會被複制;它們被多次引用,如 常用序列操作 中對 s * n 的解釋。

可變序列方法

可變序列型別還支援以下方法

sequence.append(value, /)

value 追加到序列末尾。這相當於編寫 seq[len(seq):len(seq)] = [value]

sequence.clear()

在 3.3 版本加入。

刪除 sequence 中的所有項。這相當於編寫 del sequence[:]

sequence.copy()

在 3.3 版本加入。

建立序列的淺複製。這相當於編寫 sequence[:]

提示

copy() 方法不是 MutableSequence ABC 的一部分,但大多數具體的 MutableSequence 型別都提供了它。

sequence.extend(iterable, /)

iterable 的內容擴充套件 sequence。在大多數情況下,這與編寫 seq[len(seq):len(seq)] = iterable 相同。

sequence.insert(index, value, /)

在給定 index 處將 value 插入 sequence。這相當於編寫 sequence[index:index] = [value]

sequence.pop(index=-1, /)

檢索 index 處的項,並將其從 sequence 中移除。預設情況下,刪除並返回 sequence 中的最後一項。

sequence.remove(value, /)

刪除 sequence 中第一個滿足 sequence[i] == value 的項。

如果 valuesequence 中未找到,則引發 ValueError

sequence.reverse()

就地反轉 sequence 的項。此方法在反轉大型序列時保持空間經濟性。為了提醒使用者它透過副作用操作,它返回 None

列表

列表是可變序列,通常用於儲存同質項的集合(其中同質的程度將因應用程式而異)。

class list(iterable=(), /)

列表可以通過幾種方式構建

  • 使用一對方括號表示空列表:[]

  • 使用方括號,用逗號分隔項:[a], [a, b, c]

  • 使用列表推導式:[x for x in iterable]

  • 使用型別建構函式:list()list(iterable)

建構函式構建一個列表,其項與 iterable 的項相同且順序相同。 iterable 可以是序列、支援迭代的容器或迭代器物件。如果 iterable 已經是列表,則會複製並返回該列表,類似於 iterable[:]。例如,list('abc') 返回 ['a', 'b', 'c'],而 list( (1, 2, 3) ) 返回 [1, 2, 3]。如果未提供引數,則建構函式建立一個新的空列表,[]

許多其他操作也會產生列表,包括內建的 sorted()

列表實現了所有 常用可變 序列操作。列表還提供以下附加方法

sort(*, key=None, reverse=False)

此方法就地對列表進行排序,僅使用項之間的 < 比較。不抑制異常——如果任何比較操作失敗,則整個排序操作將失敗(並且列表可能會處於部分修改狀態)。

sort() 接受兩個只能透過關鍵字傳遞的引數(關鍵字引數

key 指定一個接受一個引數的函式,該函式用於從每個列表元素中提取比較鍵(例如,key=str.lower)。為列表中的每個項計算的鍵會計算一次,然後用於整個排序過程。預設值 None 表示列表項直接排序,而無需計算單獨的鍵值。

functools.cmp_to_key() 工具可用於將 2.x 風格的 cmp 函式轉換為 key 函式。

reverse 是一個布林值。如果設定為 True,則列表元素的排序方式就像每個比較都反轉了一樣。

此方法就地修改序列,以便在對大型序列進行排序時節省空間。為了提醒使用者它透過副作用操作,它不返回已排序的序列(使用 sorted() 來顯式請求新的已排序列表例項)。

sort() 方法保證是穩定的。排序是穩定的,如果它保證不改變相等比較的元素之間的相對順序——這對於多遍排序很有用(例如,先按部門排序,再按薪資等級排序)。

有關排序示例和簡短的排序教程,請參閱排序技術

CPython 實現細節: 在對列表進行排序時,嘗試修改甚至檢查列表的效果是未定義的。Python 的 C 實現會在排序期間使列表看起來為空,並且如果它檢測到列表在排序期間被修改,則會引發 ValueError

元組

元組是不可變序列,通常用於儲存異構資料集合(例如 enumerate() 內建函式生成的 2 元組)。元組也用於需要同質資料不可變序列的情況(例如,允許儲存在 setdict 例項中)。

class tuple(iterable=(), /)

元組可以透過多種方式構建

  • 使用一對括號表示空元組:()

  • 使用尾隨逗號表示單個元組:a,(a,)

  • 用逗號分隔項:a, b, c(a, b, c)

  • 使用 tuple() 內建函式:tuple()tuple(iterable)

建構函式構建一個元組,其項與 iterable 的項相同且順序相同。 iterable 可以是序列、支援迭代的容器或迭代器物件。如果 iterable 已經是元組,則原樣返回。例如,tuple('abc') 返回 ('a', 'b', 'c'),而 tuple( [1, 2, 3] ) 返回 (1, 2, 3)。如果未提供引數,則建構函式建立一個新的空元組,()

請注意,使元組成為元組的實際上是逗號,而不是括號。括號是可選的,除非在空元組的情況下,或者當它們需要避免語法歧義時。例如,f(a, b, c) 是一個有三個引數的函式呼叫,而 f((a, b, c)) 是一個以 3 元組作為唯一引數的函式呼叫。

元組實現了所有 常用 序列操作。

對於資料異構集合,其中按名稱訪問比按索引訪問更清晰,collections.namedtuple() 可能比簡單的元組物件更合適。

範圍

range 型別表示一個不可變的數字序列,通常用於在 for 迴圈中迴圈特定次數。

class range(stop, /)
class range(start, stop, step=1, /)

範圍建構函式的引數必須是整數(可以是內建的 int 或任何實現了 __index__() 特殊方法的物件)。如果省略 step 引數,則預設為 1。如果省略 start 引數,則預設為 0。如果 step 為零,則引發 ValueError

對於正 step,範圍 r 的內容由公式 r[i] = start + step*i 確定,其中 i >= 0r[i] < stop

對於負 step,範圍的內容仍由公式 r[i] = start + step*i 確定,但約束條件是 i >= 0r[i] > stop

如果 r[0] 不滿足值約束,則範圍物件將為空。範圍確實支援負索引,但這些索引被解釋為從由正索引確定的序列末尾開始索引。

允許包含絕對值大於 sys.maxsize 的範圍,但某些功能(例如 len())可能會引發 OverflowError

範圍示例

>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(0, 30, 5))
[0, 5, 10, 15, 20, 25]
>>> list(range(0, 10, 3))
[0, 3, 6, 9]
>>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> list(range(0))
[]
>>> list(range(1, 0))
[]

範圍實現了所有 常用 序列操作,但不支援連線和重複(因為範圍物件只能表示遵循嚴格模式的序列,而重複和連線通常會違反該模式)。

start

start 引數的值(如果未提供該引數,則為 0

stop

stop 引數的值

step

step 引數的值(如果未提供該引數,則為 1

range 型別相對於普通 listtuple 的優點是,range 物件佔用的記憶體量始終相同(很小),而不管它表示的範圍大小(因為它只儲存 startstopstep 值,並按需計算單個項和子範圍)。

範圍物件實現了 collections.abc.Sequence ABC,並提供成員測試、元素索引查詢、切片和負索引支援等功能(請參閱 序列型別 — list, tuple, range)。

>>> r = range(0, 20, 2)
>>> r
range(0, 20, 2)
>>> 11 in r
False
>>> 10 in r
True
>>> r.index(10)
5
>>> r[5]
10
>>> r[:5]
range(0, 10, 2)
>>> r[-1]
18

使用 ==!= 測試範圍物件的相等性會將其作為序列進行比較。也就是說,如果兩個範圍物件代表相同的數值序列,則它們被視為相等。(請注意,兩個相等的範圍物件可能具有不同的 startstopstep 屬性,例如 range(0) == range(2, 1, 3)range(0, 3, 2) == range(0, 4, 2)。)

3.2 版更改: 實現 Sequence ABC。支援切片和負索引。以恆定時間測試 int 物件是否為成員,而不是迭代所有項。

3.3 版更改: 定義“==”和“!=”以基於它們定義的數值序列來比較範圍物件(而不是基於物件標識進行比較)。

添加了 startstopstep 屬性。

參見

  • linspace recipe 展示瞭如何實現適合浮點應用程式的惰性範圍版本。

文字和二進位制序列型別方法摘要

下表按類別總結了文字和二進位制序列型別的各種方法。

類別

str 方法

bytesbytearray 方法

格式化

str.format()

str.format_map()

f-strings

printf 風格字串格式化

printf 風格位元組格式化

搜尋和替換

str.find()

str.rfind()

bytes.find()

bytes.rfind()

str.index()

str.rindex()

bytes.index()

bytes.rindex()

str.startswith()

bytes.startswith()

str.endswith()

bytes.endswith()

str.count()

bytes.count()

str.replace()

bytes.replace()

拆分和連線

str.split()

str.rsplit()

bytes.split()

bytes.rsplit()

str.splitlines()

bytes.splitlines()

str.partition()

bytes.partition()

str.rpartition()

bytes.rpartition()

str.join()

bytes.join()

字串分類

str.isalpha()

bytes.isalpha()

str.isdecimal()

str.isdigit()

bytes.isdigit()

str.isnumeric()

str.isalnum()

bytes.isalnum()

str.isidentifier()

str.islower()

bytes.islower()

str.isupper()

bytes.isupper()

str.istitle()

bytes.istitle()

str.isspace()

bytes.isspace()

str.isprintable()

大小寫轉換

str.lower()

bytes.lower()

str.upper()

bytes.upper()

str.casefold()

str.capitalize()

bytes.capitalize()

str.title()

bytes.title()

str.swapcase()

bytes.swapcase()

填充和去除

str.ljust()

str.rjust()

bytes.ljust()

bytes.rjust()

str.center()

bytes.center()

str.expandtabs()

bytes.expandtabs()

str.strip()

bytes.strip()

str.lstrip()

str.rstrip()

bytes.lstrip()

bytes.rstrip()

轉換和編碼

str.translate()

bytes.translate()

str.maketrans()

bytes.maketrans()

str.encode()

bytes.decode()

文字序列型別 — str

Python 中的文字資料使用 str 物件,即字串來處理。字串是 Unicode code point 的不可變序列。字串字面量有多種寫法

  • 單引號:'allows embedded "double" quotes'

  • 雙引號:"allows embedded 'single' quotes"

  • 三引號:'''Three single quotes''', """Three double quotes"""

三引號字串可以跨越多行——所有相關的空格都將包含在字串字面量中。

位於單個表示式中且之間只有空格的字串字面量將被隱式轉換為單個字串字面量。也就是說,("spam " "eggs") == "spam eggs"

有關字串字面量的各種形式,包括支援的轉義序列,以及停用大多數轉義序列處理的 r(“原始”)字首,請參閱 字串和位元組字面量

還可以使用 str 建構函式從其他物件建立字串。

由於沒有單獨的“字元”型別,因此對字串進行索引會產生長度為 1 的字串。也就是說,對於非空字串 ss[0] == s[0:1]

也沒有可變的字串型別,但是 str.join()io.StringIO 可用於高效地從多個片段構建字串。

3.3 版更改: 為了與 Python 2 系列向後相容,字串字面量再次允許使用 u 字首。它對字串字面量的含義沒有影響,也不能與 r 字首結合使用。

class str(*, encoding='utf-8', errors='strict')
class str(object)
class str(object, encoding, errors='strict')
class str(object, *, errors)

返回 object字串版本。如果未提供 object,則返回空字串。否則,str() 的行為取決於是否給出了 encodingerrors,如下所示。

如果未提供 encodingerrors,則 str(object) 返回 type(object).__str__(object),這是 object 的“非正式”或易於列印的字串表示形式。對於字串物件,這是字串本身。如果 object 沒有 __str__() 方法,則 str() 會回退到返回 repr(object)

如果至少給出了 encodingerrors 中的一個,則 object 應該是類位元組物件(例如 bytesbytearray)。在這種情況下,如果 objectbytes(或 bytearray)物件,則 str(bytes, encoding, errors) 等同於 bytes.decode(encoding, errors)。否則,在呼叫 bytes.decode() 之前會獲取緩衝區物件下面的位元組物件。有關緩衝區物件的資訊,請參閱 二進位制序列型別 — bytes, bytearray, memoryview緩衝區協議

在沒有 encodingerrors 引數的情況下將 bytes 物件傳遞給 str() 屬於第一種情況,返回非正式字串表示(另請參閱 Python 命令列選項 -b)。例如

>>> str(b'Zoot!')
"b'Zoot!'"

有關 str 類及其方法的更多資訊,請參閱 文字序列型別 — str 和下面的 字串方法 部分。要輸出格式化字串,請參閱 f-strings格式字串語法 部分。此外,請參閱 文字處理服務 部分。

字串方法

字串實現了所有 常用 序列操作,以及下面描述的附加方法。

字串還支援兩種字串格式化風格,一種提供了高度的靈活性和可定製性(請參閱 str.format()格式字串語法自定義字串格式化),另一種基於 C printf 風格格式化,它處理的類型範圍較窄,並且稍微難以正確使用,但對於它能處理的情況通常速度更快(printf 風格字串格式化)。

文字處理服務 部分的標準庫涵蓋了許多提供各種文字相關實用程式的模組(包括 re 模組中的正則表示式支援)。

str.capitalize()

返回字串的副本,其中第一個字元大寫,其餘字元小寫。

3.8 版更改: 第一個字元現在被轉換為首字母大寫而不是大寫。這意味著像二合字母這樣的字元只會將第一個字母大寫,而不是整個字元。

str.casefold()

返回字串的摺疊大小寫版本。摺疊大小寫的字串可用於不區分大小寫的匹配。

摺疊大小寫類似於小寫,但更具侵略性,因為它旨在刪除字串中的所有大小寫差異。例如,德語小寫字母 'ß' 等同於 "ss"。由於它已經是小寫,lower()'ß' 不會有任何操作;casefold() 將其轉換為 "ss"

摺疊大小寫演算法在《Unicode 標準》第 3.13 節“預設大小寫摺疊”中進行了描述

在 3.3 版本加入。

str.center(width, fillchar=' ', /)

返回長度為 width 的居中字串。填充使用指定的 fillchar(預設為 ASCII 空格)。如果 width 小於或等於 len(s),則返回原始字串。例如

>>> 'Python'.center(10)
'  Python  '
>>> 'Python'.center(10, '-')
'--Python--'
>>> 'Python'.center(4)
'Python'
str.count(sub[, start[, end]])

返回子字串 sub 在範圍 [start, end] 中非重疊出現的次數。可選引數 startend 按切片表示法解釋。

如果 sub 為空,則返回字元之間空字串的數量,即字串長度加一。例如

>>> 'spam, spam, spam'.count('spam')
3
>>> 'spam, spam, spam'.count('spam', 5)
2
>>> 'spam, spam, spam'.count('spam', 5, 10)
1
>>> 'spam, spam, spam'.count('eggs')
0
>>> 'spam, spam, spam'.count('')
17
str.encode(encoding='utf-8', errors='strict')

返回編碼為 bytes 的字串。

encoding 預設為 'utf-8';有關可能的值,請參閱 標準編碼

errors 控制如何處理編碼錯誤。如果為 'strict'(預設),則引發 UnicodeError 異常。其他可能的值包括 'ignore''replace''xmlcharrefreplace''backslashreplace' 以及透過 codecs.register_error() 註冊的任何其他名稱。有關詳細資訊,請參閱 錯誤處理程式

出於效能原因,errors 的值不會在實際發生編碼錯誤、Python 開發模式 啟用或使用除錯構建 時進行有效性檢查。例如

>>> encoded_str_to_bytes = 'Python'.encode()
>>> type(encoded_str_to_bytes)
<class 'bytes'>
>>> encoded_str_to_bytes
b'Python'

3.1 版更改: 添加了對關鍵字引數的支援。

3.9 版更改: errors 引數的值現在在 Python 開發模式除錯模式 下進行檢查。

str.endswith(suffix[, start[, end]])

如果字串以指定的 suffix 結尾,則返回 True,否則返回 Falsesuffix 也可以是要查詢的字尾元組。使用可選的 start,從該位置開始測試。使用可選的 end,在此位置停止比較。使用 startend 相當於 str[start:end].endswith(suffix)。例如

>>> 'Python'.endswith('on')
True
>>> 'a tuple of suffixes'.endswith(('at', 'in'))
False
>>> 'a tuple of suffixes'.endswith(('at', 'es'))
True
>>> 'Python is amazing'.endswith('is', 0, 9)
True

另請參閱 startswith()removesuffix()

str.expandtabs(tabsize=8)

返回字串的副本,其中所有制表符都被替換為一個或多個空格,具體取決於當前列和給定的製表符大小。製表符位置每 tabsize 個字元出現一次(預設為 8,製表符位置在列 0、8、16 等處)。要展開字串,當前列設定為零,字串逐個字元進行檢查。如果字元是製表符(\t),則在結果中插入一個或多個空格字元,直到當前列等於下一個製表符位置。(製表符本身不復制。)如果字元是換行符(\n)或回車符(\r),則複製該字元,並將當前列重置為零。任何其他字元都按原樣複製,並且當前列增加一,而不考慮字元列印時的表示方式。例如

>>> '01\t012\t0123\t01234'.expandtabs()
'01      012     0123    01234'
>>> '01\t012\t0123\t01234'.expandtabs(4)
'01  012 0123    01234'
>>> print('01\t012\n0123\t01234'.expandtabs(4))
01  012
0123    01234
str.find(sub[, start[, end]])

返回子字串 sub 在切片 s[start:end] 中首次出現的最低索引。可選引數 startend 按切片表示法解釋。如果未找到 sub,則返回 -1。例如

>>> 'spam, spam, spam'.find('sp')
0
>>> 'spam, spam, spam'.find('sp', 5)
6

另請參閱 rfind()index()

備註

find() 方法僅在需要知道 sub 的位置時使用。要檢查 sub 是否為子字串,請使用 in 運算子

>>> 'Py' in 'Python'
True
str.format(*args, **kwargs)

執行字串格式化操作。呼叫此方法的字串可以包含字面文字或由花括號 {} 分隔的替換欄位。每個替換欄位包含位置引數的數字索引,或關鍵字引數的名稱。返回字串的副本,其中每個替換欄位都替換為相應引數的字串值。

>>> "The sum of 1 + 2 is {0}".format(1+2)
'The sum of 1 + 2 is 3'

有關可以在格式字串中指定的各種格式選項的說明,請參閱 格式字串語法

備註

當使用 n 型別格式化數字(intfloatcomplexdecimal.Decimal 和子類)時(例如,'{:n}'.format(1234)),該函式會臨時將 LC_CTYPE 區域設定為 LC_NUMERIC 區域,以解碼 localeconv()decimal_pointthousands_sep 欄位(如果它們是非 ASCII 或長度超過 1 位元組),並且 LC_NUMERIC 區域與 LC_CTYPE 區域不同。此臨時更改會影響其他執行緒。

3.7 版更改: 當使用 n 型別格式化數字時,該函式在某些情況下會臨時將 LC_CTYPE 區域設定為 LC_NUMERIC 區域。

str.format_map(mapping, /)

類似於 str.format(**mapping),但 mapping 直接使用而不復制到 dict。這在例如 mapping 是 dict 子類時很有用。

>>> class Default(dict):
...     def __missing__(self, key):
...         return key
...
>>> '{name} was born in {country}'.format_map(Default(name='Guido'))
'Guido was born in country'

在 3.2 版本加入。

str.index(sub[, start[, end]])

find() 類似,但在找不到子字串時引發 ValueError

str.isalnum()

如果字串中的所有字元都是字母數字並且至少有一個字元,則返回 True,否則返回 False。字元 c 是字母數字的,如果以下任一返回 Truec.isalpha()c.isdecimal()c.isdigit()c.isnumeric()

str.isalpha()

如果字串中的所有字元都是字母並且至少有一個字元,則返回 True,否則返回 False。字母字元是 Unicode 字元資料庫中定義為“Letter”的字元,即具有通用類別屬性為“Lm”、“Lt”、“Lu”、“Ll”或“Lo”之一的字元。請注意,這與《Unicode 標準》第 4.10 節“字母、字母和表意字元”中定義的字母屬性不同。

str.isascii()

如果字串為空或字串中的所有字元都是 ASCII 字元,則返回 True,否則返回 False。ASCII 字元的程式碼點在 U+0000-U+007F 範圍內。

在 3.7 版本加入。

str.isdecimal()

如果字串中的所有字元都是十進位制字元並且至少有一個字元,則返回 True,否則返回 False。十進位制字元是可用於形成十進位制數的字元,例如 U+0660、阿拉伯-印度數字零。形式上,十進位制字元是 Unicode 通用類別“Nd”中的字元。

str.isdigit()

如果字串中的所有字元都是數字,並且至少有一個字元,則返回True,否則返回False。數字包括十進位制字元和需要特殊處理的數字,例如相容的上標數字。這包括不能用於構成十進位制數字的數字,如迦羅什文字數字。形式上,數字是具有屬性值Numeric_Type=DigitNumeric_Type=Decimal的字元。

str.isidentifier()

如果字串是有效的識別符號(根據語言定義,請參閱名稱(識別符號和關鍵字)部分),則返回True

可以使用keyword.iskeyword()來測試字串s是否為保留識別符號,例如defclass

示例

>>> from keyword import iskeyword

>>> 'hello'.isidentifier(), iskeyword('hello')
(True, False)
>>> 'def'.isidentifier(), iskeyword('def')
(True, True)
str.islower()

如果字串中的所有可區分大小寫的字元[4]均為小寫,並且至少有一個可區分大小寫的字元,則返回True,否則返回False

str.isnumeric()

如果字串中的所有字元都是數字字元,並且至少有一個字元,則返回True,否則返回False。數字字元包括數字字元以及具有 Unicode 數字值屬性的所有字元,例如 U+2155, VULGAR FRACTION ONE FIFTH。形式上,數字字元是那些屬性值為Numeric_Type=Digit, Numeric_Type=DecimalNumeric_Type=Numeric 的字元。

str.isprintable()

如果字串中的所有字元都是可列印字元,則返回True;如果字串包含至少一個不可列印字元,則返回False

這裡的“可列印”是指該字元適合repr()用於其輸出;“不可列印”是指repr()對內建型別會對其進行十六進位制轉義。這不影響寫入sys.stdoutsys.stderr的字串的處理。

可列印字元是指在 Unicode 字元資料庫(請參閱unicodedata)中,其常規類別屬於字母(Letter)、標記(Mark)、數字(Number)、標點(Punctuation)或符號(Symbol)組(L、M、N、P 或 S);再加上 ASCII 空格 0x20。不可列印字元是指屬於分隔符(Separator)或其它(Other)組(Z 或 C)的字元,但不包括 ASCII 空格。

str.isspace()

如果字串中只有空白字元並且至少有一個字元,則返回True,否則返回False

一個字元是空白字元,如果在 Unicode 字元資料庫(請參閱unicodedata)中,其常規類別是'Zs'(“分隔符,空格”),或者其雙向類是'WS''B''S' 之一。

str.istitle()

如果字串是標題化的字串並且至少有一個字元(例如,大寫字元只能跟在非大小寫字元後面,小寫字元只能跟在大小寫字元後面),則返回True。否則返回False

例如:

>>> 'Spam, Spam, Spam'.istitle()
True
>>> 'spam, spam, spam'.istitle()
False
>>> 'SPAM, SPAM, SPAM'.istitle()
False

另請參閱title()

str.isupper()

如果字串中的所有可區分大小寫的字元[4]均為大寫,並且至少有一個可區分大小寫的字元,則返回True,否則返回False

>>> 'BANANA'.isupper()
True
>>> 'banana'.isupper()
False
>>> 'baNana'.isupper()
False
>>> ' '.isupper()
False
str.join(iterable, /)

返回一個字串,該字串是iterable中字串的連線。如果iterable中有任何非字串值(包括bytes物件),則將引發TypeError。元素之間的分隔符是提供此方法的字串。

str.ljust(width, fillchar=' ', /)

返回一個長度為width的字串,其中字串左對齊。填充使用指定的fillchar(預設為ASCII空格)。如果width小於或等於len(s),則返回原始字串。

str.lower()

返回字串的一個副本,其中所有可區分大小寫的字元[4]都轉換為小寫。

使用的降級演算法在《Unicode 標準》第 3.13 節“預設大小寫摺疊”中進行了描述

str.lstrip(chars=None, /)

返回字串的一個副本,其中刪除前導字元。chars 引數是一個指定要刪除的字元集的字串。如果省略或為None,則chars 引數預設為刪除空白字元。chars 引數不是字首;而是,其值的所有組合都會被剝離。

>>> '   spacious   '.lstrip()
'spacious   '
>>> 'www.example.com'.lstrip('cmowz.')
'example.com'

請參閱str.removeprefix()方法,該方法將刪除單個字首字串而不是所有字元集。例如

>>> 'Arthur: three!'.lstrip('Arthur: ')
'ee!'
>>> 'Arthur: three!'.removeprefix('Arthur: ')
'three!'
static str.maketrans(dict, /)
static str.maketrans(from, to, remove='', /)

此靜態方法返回一個可用於str.translate()的翻譯表。

如果只有一個引數,則它必須是一個字典,將 Unicode 序數(整數)或字元(長度為 1 的字串)對映到 Unicode 序數、字串(任意長度)或None。字元鍵隨後將被轉換為序數。

如果有兩個引數,它們必須是等長的字串,並且在生成的字典中,from中的每個字元將對映到to中相同位置的字元。如果存在第三個引數,則它必須是一個字串,該字串中的字元將被對映到結果中的None

str.partition(sep, /)

在第一次出現sep時分割字串,並返回一個包含分隔符之前的部分、分隔符本身以及分隔符之後的部分的 3 元組。如果找不到分隔符,則返回一個包含字串本身,後跟兩個空字串的 3 元組。

str.removeprefix(prefix, /)

如果字串以prefix字串開頭,則返回string[len(prefix):]。否則,返回原始字串的副本。

>>> 'TestHook'.removeprefix('Test')
'Hook'
>>> 'BaseTestCase'.removeprefix('Test')
'BaseTestCase'

在 3.9 版本中新增。

str.removesuffix(suffix, /)

如果字串以suffix字串結尾且suffix不為空,則返回string[:-len(suffix)]。否則,返回原始字串的副本。

>>> 'MiscTests'.removesuffix('Tests')
'Misc'
>>> 'TmpDirMixin'.removesuffix('Tests')
'TmpDirMixin'

在 3.9 版本中新增。

str.replace(old, new, /, count=-1)

返回字串的副本,其中所有出現的子字串old都被替換為new。如果給出了count,則只替換前count個出現。如果未指定count或為-1,則替換所有出現。

版本 3.13 中已更改: count現在可以作為關鍵字引數支援。

str.rfind(sub[, start[, end]])

返回字串中子字串sub出現處的最高索引,使得sub包含在s[start:end]內。可選引數startend的解釋方式與切片表示法相同。失敗時返回-1

str.rindex(sub[, start[, end]])

rfind()類似,但在找不到子字串sub時引發ValueError

str.rjust(width, fillchar=' ', /)

返回一個長度為width的字串,其中字串右對齊。填充使用指定的fillchar(預設為ASCII空格)。如果width小於或等於len(s),則返回原始字串。

str.rpartition(sep, /)

在最後一次出現sep時分割字串,並返回一個包含分隔符之前的部分、分隔符本身以及分隔符之後的部分的 3 元組。如果找不到分隔符,則返回一個包含兩個空字串,後跟字串本身的 3 元組。

str.rsplit(sep=None, maxsplit=-1)

返回字串中單詞的列表,使用sep作為分隔符字串。如果給出了maxsplit,則最多進行maxsplit次分割,即最右邊的分割。如果未指定sep或為None,則任何空白字串都是分隔符。除了從右側分割之外,rsplit()的行為與下面詳細介紹的split()相同。

str.rstrip(chars=None, /)

返回字串的一個副本,其中刪除尾隨字元。chars 引數是一個指定要刪除的字元集的字串。如果省略或為None,則chars 引數預設為刪除空白字元。chars 引數不是字尾;而是,其值的所有組合都會被剝離。

>>> '   spacious   '.rstrip()
'   spacious'
>>> 'mississippi'.rstrip('ipz')
'mississ'

請參閱str.removesuffix()方法,該方法將刪除單個字尾字串而不是所有字元集。例如

>>> 'Monty Python'.rstrip(' Python')
'M'
>>> 'Monty Python'.removesuffix(' Python')
'Monty'
str.split(sep=None, maxsplit=-1)

返回字串中單詞的列表,使用sep作為分隔符字串。如果給出了maxsplit,則最多進行maxsplit次分割(因此,列表最多包含maxsplit+1個元素)。如果未指定maxsplit或為-1,則對分割次數沒有限制(進行所有可能的分割)。

如果給出了sep,則連續的分隔符不會被分組在一起,並被視為分隔空字串(例如,'1,,2'.split(',')返回['1', '', '2'])。sep引數可以包含多個字元作為一個分隔符(要使用多個分隔符進行分割,請使用re.split())。分割空字串時,如果指定了分隔符,則返回['']

例如:

>>> '1,2,3'.split(',')
['1', '2', '3']
>>> '1,2,3'.split(',', maxsplit=1)
['1', '2,3']
>>> '1,2,,3,'.split(',')
['1', '2', '', '3', '']
>>> '1<>2<>3<4'.split('<>')
['1', '2', '3<4']

如果未指定sep或為None,則應用不同的分割演算法:連續的空白字元被視為單個分隔符,並且結果不包含開頭或結尾的空字串(如果字串有前導或尾隨空白)。因此,使用None分隔符分割空字串或僅包含空白字元的字串將返回[]

例如:

>>> '1 2 3'.split()
['1', '2', '3']
>>> '1 2 3'.split(maxsplit=1)
['1', '2 3']
>>> '   1   2   3   '.split()
['1', '2', '3']

如果未指定sep或為Nonemaxsplit0,則僅考慮前導的連續空白字元。

例如:

>>> "".split(None, 0)
[]
>>> "   ".split(None, 0)
[]
>>> "   foo   ".split(maxsplit=0)
['foo   ']
str.splitlines(keepends=False)

返回字串中行的列表,按行邊界斷開。除非指定了keepends且其值為真,否則行邊界不會包含在生成的列表中。

此方法根據以下行邊界進行分割。特別是,這些邊界是通用換行符的超集。

表示

描述

\n

換行符

\r

回車符

\r\n

回車符+換行符

\v\x0b

垂直製表符

\f\x0c

換頁符

\x1c

檔案分隔符

\x1d

組分隔符

\x1e

記錄分隔符

\x85

換行(C1 控制碼)

\u2028

行分隔符

\u2029

段落分隔符

版本 3.2 中已更改: \v\f已新增到行邊界列表中。

例如:

>>> 'ab c\n\nde fg\rkl\r\n'.splitlines()
['ab c', '', 'de fg', 'kl']
>>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True)
['ab c\n', '\n', 'de fg\r', 'kl\r\n']

與給定分隔符字串sepsplit()不同,此方法對於空字串返回一個空列表,並且末尾的換行符不會產生額外的行。

>>> "".splitlines()
[]
>>> "One line\n".splitlines()
['One line']

作為比較,split('\n')的結果是

>>> ''.split('\n')
['']
>>> 'Two lines\n'.split('\n')
['Two lines', '']
str.startswith(prefix[, start[, end]])

如果字串以prefix開頭,則返回True,否則返回Falseprefix也可以是用於搜尋的字首元組。使用可選的start,從該位置開始測試字串。使用可選的end,在此位置停止比較字串。

str.strip(chars=None, /)

返回字串的一個副本,其中刪除前導和尾隨字元。chars 引數是一個指定要刪除的字元集的字串。如果省略或為None,則chars 引數預設為刪除空白字元。chars 引數不是字首或字尾;而是,其值的所有組合都會被剝離。

>>> '   spacious   '.strip()
'spacious'
>>> 'www.example.com'.strip('cmowz.')
'example'

最外層的前導和尾隨chars引數值將從字串中剝離。字元會從前導末尾開始刪除,直到遇到字串中不包含在chars字元集中的字元。類似的操作會在尾隨末尾進行。例如

>>> comment_string = '#....... Section 3.2.1 Issue #32 .......'
>>> comment_string.strip('.#! ')
'Section 3.2.1 Issue #32'
str.swapcase()

返回字串的一個副本,其中大寫字元轉換為小寫,反之亦然。請注意,s.swapcase().swapcase() == s並不總是成立。

str.title()

返回字串的標題化版本,其中單詞以大寫字母開頭,其餘字元為小寫。

例如:

>>> 'Hello world'.title()
'Hello World'

該演算法使用一種簡單的、與語言無關的單詞定義,即將單詞定義為連續字母的組。該定義在許多情況下都有效,但這意味著縮寫和所有格中的撇號會形成單詞邊界,這可能不是期望的結果。

>>> "they're bill's friends from the UK".title()
"They'Re Bill'S Friends From The Uk"

string.capwords()函式沒有這個問題,因為它只按空格分割單詞。

或者,可以使用正則表示式來解決撇號的問題。

>>> import re
>>> def titlecase(s):
...     return re.sub(r"[A-Za-z]+('[A-Za-z]+)?",
...                   lambda mo: mo.group(0).capitalize(),
...                   s)
...
>>> titlecase("they're bill's friends.")
"They're Bill's Friends."

另請參閱istitle()

str.translate(table, /)

返回字串的副本,其中每個字元都已透過指定的翻譯表進行對映。該表必須是一個透過__getitem__()實現索引的物件,通常是對映序列。當透過 Unicode 序數(整數)進行索引時,該表物件可以執行以下任何操作:返回一個 Unicode 序數或字串,將字元對映到一個或多個其他字元;返回None,將字元從返回字串中刪除;或者引發LookupError異常,將字元對映到其自身。

您可以使用str.maketrans()從不同格式的字元到字元對映建立翻譯對映。

另請參閱codecs模組,以獲得更靈活的自定義字元對映方法。

str.upper()

返回字串的一個副本,其中所有可區分大小寫的字元[4]都轉換為大寫。請注意,如果s包含非大小寫字元,或者如果結果字元的 Unicode 類別不是“Lu”(字母,大寫),而是例如“Lt”(字母,標題化),則s.upper().isupper()可能為False

使用的升級演算法在《Unicode 標準》第 3.13 節“預設大小寫摺疊”中進行了描述

str.zfill(width, /)

返回字串的副本,在左側填充 ASCII '0'數字,使其長度為width。前導符號字首('+'/'-')的處理方式是將填充符插入在符號字元之後而不是之前。如果width小於或等於len(s),則返回原始字串。

例如:

>>> "42".zfill(5)
'00042'
>>> "-42".zfill(5)
'-0042'

格式化字串字面量(f-string)

在 3.6 版本加入。

版本 3.7 中已更改: awaitasync for可以在 f-string 中的表示式中使用。

版本 3.8 中已更改: 添加了除錯運算子(=)。

版本 3.12 中已更改: f-string 中的表示式的許多限制已被移除。特別是,現在允許巢狀字串、註釋和反斜槓。

f-string(形式上是格式化字串字面量)是以fF為字首的字串字面量。這種型別的字串字面量允許將任意 Python 表示式嵌入到替換欄位中,替換欄位由花括號({})分隔。這些表示式在執行時進行求值,類似於str.format(),並被轉換為常規的str物件。例如

>>> who = 'nobody'
>>> nationality = 'Spanish'
>>> f'{who.title()} expects the {nationality} Inquisition!'
'Nobody expects the Spanish Inquisition!'

也可以使用多行 f-string。

>>> f'''This is a string
... on two lines'''
'This is a string\non two lines'

單個開花括號'{'標記一個替換欄位,它可以包含任何 Python 表示式。

>>> nationality = 'Spanish'
>>> f'The {nationality} Inquisition!'
'The Spanish Inquisition!'

要包含字面量{},請使用雙括號。

>>> x = 42
>>> f'{{x}} is {x}'
'{x} is 42'

也可以使用函式,以及格式說明符

>>> from math import sqrt
>>> f'√2 \N{ALMOST EQUAL TO} {sqrt(2):.5f}'
'√2 ≈ 1.41421'

任何非字串表示式都預設使用str()進行轉換。

>>> from fractions import Fraction
>>> f'{Fraction(1, 3)}'
'1/3'

要使用顯式轉換,請使用!(感嘆號)運算子,後跟任何有效的格式,這些格式是:

轉換

含義

!a

ascii()

!r

repr()

!s

str()

例如:

>>> from fractions import Fraction
>>> f'{Fraction(1, 3)!s}'
'1/3'
>>> f'{Fraction(1, 3)!r}'
'Fraction(1, 3)'
>>> question = '¿Dónde está el Presidente?'
>>> print(f'{question!a}')
'\xbfD\xf3nde est\xe1 el Presidente?'

在除錯時,透過使用等號(=)跟在表示式後面,可以同時查看錶達式及其值。這會保留方括號內的空格,並可與轉換器一起使用。預設情況下,除錯運算子使用repr()!r)轉換。例如

>>> from fractions import Fraction
>>> calculation = Fraction(1, 3)
>>> f'{calculation=}'
'calculation=Fraction(1, 3)'
>>> f'{calculation = }'
'calculation = Fraction(1, 3)'
>>> f'{calculation = !s}'
'calculation = 1/3'

一旦輸出了求值,就可以使用冒號(':')後面的格式說明符對其進行格式化。在表示式求值(可能已轉換為字串)後,會使用格式說明符(如果沒有給出格式說明符,則為空字串)呼叫結果的__format__()方法。然後使用格式化結果作為替換欄位的最終值。例如

>>> from fractions import Fraction
>>> f'{Fraction(1, 7):.6f}'
'0.142857'
>>> f'{Fraction(1, 7):_^+10}'
'___+1/7___'

`printf`風格的字串格式化

備註

此處描述的格式化操作表現出各種細微差別,導致許多常見錯誤(例如,無法正確顯示元組和字典)。

使用格式化字串字面量str.format()介面或string.Template可能有助於避免這些錯誤。這些替代方法中的每一種都提供了各自的權衡和優點,如簡潔性、靈活性和/或可擴充套件性。

字串物件有一個獨特內建操作:%運算子(模)。這也稱為字串格式化插值運算子。給定format % values(其中format是字串),format中的%轉換規範會被values中的零個或多個項替換。效果類似於 C 語言中的sprintf()函式。例如

>>> print('%s has %d quote types.' % ('Python', 2))
Python has 2 quote types.

如果format需要單個引數,則values可以是單個非元組物件。[5]否則,values必須是一個元組,其中包含格式字串指定的專案數,或者是一個單一的對映物件(例如,字典)。

轉換規範包含兩個或更多個字元,並具有以下組成部分,它們必須按此順序出現:

  1. 標記規範開頭的'%'字元。

  2. 對映鍵(可選),由一系列括號括起來的字元組成(例如,(somename))。

  3. 轉換標誌(可選),它們會影響某些轉換型別的結果。

  4. 最小欄位寬度(可選)。如果指定為'*'(星號),則實際寬度將從values中的下一個元素讀取,要轉換的物件將出現在最小欄位寬度和可選精度之後。

  5. 精度(可選),給出為'.'(點)後跟精度。如果指定為'*'(星號),則實際精度將從values中的下一個元素讀取,要轉換的值將出現在精度之後。

  6. 長度修改符(可選)。

  7. 轉換型別。

當右引數是字典(或其他對映型別)時,字串中的格式必須包括一個緊跟在'%'字元之後的、指向該字典的括號對映鍵。對映鍵從對映中選擇要格式化的值。例如

>>> print('%(language)s has %(number)03d quote types.' %
...       {'language': "Python", "number": 2})
Python has 002 quote types.

在這種情況下,格式中可能不會出現*規範(因為它們需要順序引數列表)。

轉換標誌字元是:

Flag

含義

'#'

轉換將使用“備用形式”(如下定義)。

'0'

對於數字值,轉換將使用零填充。

'-'

轉換將左對齊(如果兩者都給出,則覆蓋'0'轉換)。

' '

(空格)在有符號轉換產生的正數(或空字串)之前應留有一個空格。

'+'

符號字元('+''-')將出現在轉換之前(覆蓋“空格”標誌)。

長度修改符(h, l, 或 L)可能存在,但在 Python 中被忽略,因為它們不是必需的——所以例如%ld%d相同。

轉換型別是:

轉換

含義

備註

'd'

帶符號整數十進位制。

'i'

帶符號整數十進位制。

'o'

帶符號八進位制值。

(1)

'u'

已棄用的型別——它與'd'相同。

(6)

'x'

帶符號十六進位制(小寫)。

(2)

'X'

帶符號十六進位制(大寫)。

(2)

'e'

浮點指數格式(小寫)。

(3)

'E'

浮點指數格式(大寫)。

(3)

'f'

浮點十進位制格式。

(3)

'F'

浮點十進位制格式。

(3)

'g'

浮點格式。當指數小於 -4 或不小於精度時,使用小寫指數格式,否則使用十進位制格式。

(4)

'G'

浮點格式。當指數小於 -4 或不小於精度時,使用大寫指數格式,否則使用十進位制格式。

(4)

'c'

單個字元(接受整數或單字元字串)。

'r'

字串(使用repr()將任何 Python 物件轉換為字串)。

(5)

's'

字串(使用str()將任何 Python 物件轉換為字串)。

(5)

'a'

字串(使用ascii()將任何 Python 物件轉換為字串)。

(5)

'%'

不轉換引數,結果中產生一個'%'字元。

備註

  1. 備用形式會在第一個數字之前插入一個前導八進位制說明符('0o')。

  2. 備用形式會在第一個數字之前插入一個前導'0x''0X'(取決於使用的是'x'還是'X'格式)。

  3. 備用形式會導致結果始終包含小數點,即使小數點後面沒有數字。

    精度決定小數點後的位數,預設為 6。

  4. 備用形式會導致結果始終包含小數點,並且尾隨零不會像通常那樣被刪除。

    精度決定小數點前後有效數字的位數,預設為 6。

  5. 如果精度為N,則輸出將截斷為N個字元。

  6. 請參閱PEP 237

由於 Python 字串具有顯式長度,%s轉換不會假定'\0'是字串的結尾。

版本 3.1 中已更改: 絕對值大於 1e50 的數字的%f轉換不再被替換為%g轉換。

二進位制序列型別 — bytes, bytearray, memoryview

用於處理二進位制資料的核心內建型別是bytesbytearray。它們由memoryview支援,該類使用緩衝區協議訪問其他二進位制物件的記憶體,而無需複製。

array模組支援高效儲存基本資料型別,如 32 位整數和 IEEE754 雙精度浮點值。

位元組物件

位元組物件是單個位元組的不可變序列。由於許多主要的二進位制協議都基於 ASCII 文字編碼,因此位元組物件提供了許多僅在處理 ASCII 相容資料時才有效的方法,並且在許多其他方面與字串物件密切相關。

class bytes(source=b'')
class bytes(source, encoding, errors='strict')

首先,位元組字面量的語法與字串字面量的語法基本相同,只是添加了一個b字首。

  • 單引號:b'still allows embedded "double" quotes'

  • 雙引號:b"still allows embedded 'single' quotes"

  • 三引號:b'''3 single quotes''', b"""3 double quotes"""

位元組字面量僅允許 ASCII 字元(無論宣告的原始碼編碼如何)。任何大於 127 的二進位制值必須在位元組字面量中使用適當的轉義序列表示。

與字串字面量一樣,位元組字面量也可以使用r字首來停用轉義序列的處理。有關各種位元組字面量形式(包括支援的轉義序列)的更多資訊,請參閱字串和位元組字面量

雖然位元組字面量和表示基於 ASCII 文字,但位元組物件實際上表現為整數的不可變序列,其中序列中的每個值都受到限制,即0 <= x < 256(嘗試違反此限制將觸發ValueError)。這樣做是特意的,以強調雖然許多二進位制格式包含基於 ASCII 的元素並且可以有效地使用一些面向文字的演算法進行處理,但這通常不適用於任意二進位制資料(盲目地將文字處理演算法應用於不相容 ASCII 的二進位制資料格式通常會導致資料損壞)。

除了字面量形式之外,還可以透過其他多種方式建立位元組物件:

  • 指定長度的零填充位元組物件:bytes(10)

  • 從整數的可迭代物件:bytes(range(20))

  • 透過緩衝區協議複製現有二進位制資料:bytes(obj)

另請參閱bytes內建函式。

由於 2 個十六進位制數字精確對應一個位元組,因此十六進位制數是描述二進位制資料的常用格式。因此,bytes 型別有一個額外的類方法來以該格式讀取資料:

classmethod fromhex(string, /)

bytes類方法返回一個位元組物件,解碼給定的字串物件。字串必須包含每個位元組兩個十六進位制數字,並忽略 ASCII 空白。

>>> bytes.fromhex('2Ef0 F1f2  ')
b'.\xf0\xf1\xf2'

版本 3.7 中已更改: bytes.fromhex()現在會跳過字串中的所有 ASCII 空白,而不僅僅是空格。

版本 3.14 中已更改: bytes.fromhex()現在接受 ASCII bytes類似位元組的物件作為輸入。

存在一個反向轉換函式,用於將位元組物件轉換為其十六進位制表示。

hex(*, bytes_per_sep=1)
hex(sep, bytes_per_sep=1)

返回一個字串物件,其中包含例項中每個位元組的兩個十六進位制數字。

>>> b'\xf0\xf1\xf2'.hex()
'f0f1f2'

如果您想使十六進位制字串更易讀,可以指定一個單獨的字元分隔符sep引數包含在輸出中。預設情況下,此分隔符將包含在每個位元組之間。第二個可選bytes_per_sep引數控制間距。正值從右側計算分隔符位置,負值從左側計算。

>>> value = b'\xf0\xf1\xf2'
>>> value.hex('-')
'f0-f1-f2'
>>> value.hex('_', 2)
'f0_f1f2'
>>> b'UUDDLRLRAB'.hex(' ', -4)
'55554444 4c524c52 4142'

在 3.5 版本加入。

版本 3.8 中已更改: bytes.hex()現在支援可選的sepbytes_per_sep引數,以在十六進位制輸出的位元組之間插入分隔符。

由於位元組物件是整數序列(類似於元組),對於位元組物件bb[0]將是一個整數,而b[0:1]將是一個長度為 1 的位元組物件。(這與文字字串形成對比,在文字字串中,索引和切片都會生成長度為 1 的字串)

位元組物件的表示使用字面量格式(b'...'),因為它通常比例如bytes([46, 46, 46])更有用。您始終可以使用list(b)將位元組物件轉換為整數列表。

位元組陣列物件

bytearray物件是bytes物件的可變對應物。

class bytearray(source=b'')
class bytearray(source, encoding, errors='strict')

沒有專門的位元組陣列物件字面量語法,而是始終透過呼叫建構函式來建立它們:

  • 建立空例項:bytearray()

  • 使用給定長度建立零填充例項:bytearray(10)

  • 從整數的可迭代物件:bytearray(range(20))

  • 透過緩衝區協議複製現有二進位制資料:bytearray(b'Hi!')

由於位元組陣列物件是可變的,因此它們除了位元組和位元組陣列操作中描述的常用位元組和位元組陣列操作外,還支援可變序列操作。

另請參閱bytearray內建函式。

由於 2 個十六進位制數字精確對應一個位元組,因此十六進位制數是描述二進位制資料的常用格式。因此,bytearray 型別有一個額外的類方法來以該格式讀取資料:

classmethod fromhex(string, /)

bytearray類方法返回一個 bytearray 物件,解碼給定的字串物件。字串必須包含每個位元組兩個十六進位制數字,並忽略 ASCII 空白。

>>> bytearray.fromhex('2Ef0 F1f2  ')
bytearray(b'.\xf0\xf1\xf2')

版本 3.7 中已更改: bytearray.fromhex()現在會跳過字串中的所有 ASCII 空白,而不僅僅是空格。

版本 3.14 中已更改: bytearray.fromhex()現在接受 ASCII bytes類似位元組的物件作為輸入。

存在一個反向轉換函式,用於將 bytearray 物件轉換為其十六進位制表示。

hex(*, bytes_per_sep=1)
hex(sep, bytes_per_sep=1)

返回一個字串物件,其中包含例項中每個位元組的兩個十六進位制數字。

>>> bytearray(b'\xf0\xf1\xf2').hex()
'f0f1f2'

在 3.5 版本加入。

版本 3.8 中已更改: bytes.hex()類似,bytearray.hex()現在支援可選的sepbytes_per_sep引數,以在十六進位制輸出的位元組之間插入分隔符。

resize(size, /)

bytearray的大小調整為包含size位元組。size必須大於或等於 0。

如果bytearray需要縮小,則超出size的位元組將被截斷。

如果bytearray需要增長,則所有新位元組,即超出size的位元組,都將設定為 null 位元組。

這等價於:

>>> def resize(ba, size):
...     if len(ba) > size:
...         del ba[size:]
...     else:
...         ba += b'\0' * (size - len(ba))

示例:

>>> shrink = bytearray(b'abc')
>>> shrink.resize(1)
>>> (shrink, len(shrink))
(bytearray(b'a'), 1)
>>> grow = bytearray(b'abc')
>>> grow.resize(5)
>>> (grow, len(grow))
(bytearray(b'abc\x00\x00'), 5)

在 3.14 版本加入。

由於位元組陣列物件是整數序列(類似於列表),對於位元組陣列物件bb[0]將是一個整數,而b[0:1]將是一個長度為 1 的位元組陣列物件。(這與文字字串形成對比,在文字字串中,索引和切片都會生成長度為 1 的字串)

位元組陣列物件的表示使用位元組字面量格式(bytearray(b'...')),因為它通常比例如bytearray([46, 46, 46])更有用。您始終可以使用list(b)將位元組陣列物件轉換為整數列表。

位元組和位元組陣列操作

bytes 和 bytearray 物件都支援 通用 序列操作。它們不僅可以與同類型的運算元互操作,還可以與任何 類位元組物件 互操作。由於這種靈活性,它們可以在操作中自由混合而不會導致錯誤。但是,結果的返回型別可能取決於運算元的順序。

備註

bytes 和 bytearray 物件上的方法不接受字串作為引數,就像字串上的方法不接受位元組作為引數一樣。例如,你必須這樣寫:

a = "abc"
b = a.replace("a", "f")

a = b"abc"
b = a.replace(b"a", b"f")

某些 bytes 和 bytearray 操作假定使用 ASCII 相容的二進位制格式,因此在處理任意二進位制資料時應避免使用。這些限制在下面介紹。

備註

使用這些基於 ASCII 的操作來處理非 ASCII 格式儲存的二進位制資料可能會導致資料損壞。

bytes 和 bytearray 物件上的以下方法可用於處理任意二進位制資料。

bytes.count(sub[, start[, end]])
bytearray.count(sub[, start[, end]])

返回子序列 sub 在範圍 [start, end] 內非重疊出現的次數。可選引數 startend 的解釋方式與切片表示法相同。

要搜尋的子序列可以是任何 類位元組物件 或 0 到 255 範圍內的整數。

如果 sub 為空,則返回字元之間的空切片數,即位元組物件長度加一。

版本 3.3 中已更改: 現在也接受 0 到 255 範圍內的整數作為子序列。

bytes.removeprefix(prefix, /)
bytearray.removeprefix(prefix, /)

如果二進位制資料以 prefix 字串開頭,則返回 bytes[len(prefix):]。否則,返回原始二進位制資料的副本。

>>> b'TestHook'.removeprefix(b'Test')
b'Hook'
>>> b'BaseTestCase'.removeprefix(b'Test')
b'BaseTestCase'

prefix 可以是任何 類位元組物件

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

在 3.9 版本中新增。

bytes.removesuffix(suffix, /)
bytearray.removesuffix(suffix, /)

如果二進位制資料以 suffix 字串結尾且該 suffix 非空,則返回 bytes[:-len(suffix)]。否則,返回原始二進位制資料的副本。

>>> b'MiscTests'.removesuffix(b'Tests')
b'Misc'
>>> b'TmpDirMixin'.removesuffix(b'Tests')
b'TmpDirMixin'

suffix 可以是任何 類位元組物件

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

在 3.9 版本中新增。

bytes.decode(encoding='utf-8', errors='strict')
bytearray.decode(encoding='utf-8', errors='strict')

將位元組解碼為 str

encoding 預設為 'utf-8';有關可能的值,請參閱 標準編碼

errors 控制如何處理解碼錯誤。如果為 'strict'(預設值),則會引發 UnicodeError 異常。其他可能的值包括 'ignore''replace',以及透過 codecs.register_error() 註冊的任何其他名稱。有關詳細資訊,請參閱 錯誤處理程式

出於效能原因,除非實際發生解碼錯誤,Python 開發模式 已啟用或使用了 除錯構建,否則 errors 的值不會被檢查有效性。

備註

encoding 引數傳遞給 str 可以直接解碼任何 類位元組物件,而無需建立臨時的 bytesbytearray 物件。

3.1 版更改: 添加了對關鍵字引數的支援。

3.9 版更改: errors 引數的值現在在 Python 開發模式除錯模式 下進行檢查。

bytes.endswith(suffix[, start[, end]])
bytearray.endswith(suffix[, start[, end]])

如果二進位制資料以指定的 suffix 結尾,則返回 True,否則返回 Falsesuffix 也可以是用於查詢的字尾元組。使用可選的 start,從該位置開始測試。使用可選的 end,在該位置停止比較。

要搜尋的字尾可以是任何 類位元組物件

bytes.find(sub[, start[, end]])
bytearray.find(sub[, start[, end]])

返回資料中子序列 sub 第一次出現時的最低索引,使得 sub 包含在切片 s[start:end] 中。可選引數 startend 的解釋方式與切片表示法相同。如果找不到 sub,則返回 -1

要搜尋的子序列可以是任何 類位元組物件 或 0 到 255 範圍內的整數。

備註

如果只需要知道 sub 的位置,則應使用 find() 方法。要檢查 sub 是否為子字串,請使用 in 運算子。

>>> b'Py' in b'Python'
True

版本 3.3 中已更改: 現在也接受 0 到 255 範圍內的整數作為子序列。

bytes.index(sub[, start[, end]])
bytearray.index(sub[, start[, end]])

find() 類似,但在找不到子序列時引發 ValueError

要搜尋的子序列可以是任何 類位元組物件 或 0 到 255 範圍內的整數。

版本 3.3 中已更改: 現在也接受 0 到 255 範圍內的整數作為子序列。

bytes.join(iterable, /)
bytearray.join(iterable, /)

返回一個 bytes 或 bytearray 物件,它是 iterable 中二進位制資料序列的連線。如果 iterable 中存在任何不是 類位元組物件(包括 str 物件)的值,則會引發 TypeError。元素之間的分隔符是提供此方法的 bytes 或 bytearray 物件的內容。

static bytes.maketrans(from, to, /)
static bytearray.maketrans(from, to, /)

此靜態方法返回一個可用於 bytes.translate() 的轉換表,該表會將 from 中的每個字元對映到 to 中相同位置的字元;fromto 都必須是 類位元組物件 且長度相同。

在 3.1 版本加入。

bytes.partition(sep, /)
bytearray.partition(sep, /)

在第一次出現 sep 的位置拆分序列,並返回一個包含分隔符之前的部分、分隔符本身或其 bytearray 副本以及分隔符之後的部分的 3 元組。如果找不到分隔符,則返回一個包含原始序列副本、後跟兩個空 bytes 或 bytearray 物件的 3 元組。

要搜尋的分隔符可以是任何 類位元組物件

bytes.replace(old, new, count=-1, /)
bytearray.replace(old, new, count=-1, /)

返回序列的副本,其中所有子序列 old 的出現都被 new 替換。如果給出了可選引數 count,則只替換前 count 次出現。

要搜尋的子序列及其替換可以是任何 類位元組物件

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.rfind(sub[, start[, end]])
bytearray.rfind(sub[, start[, end]])

返回序列中子序列 sub 第一次出現時的最高索引,使得 sub 包含在 s[start:end] 中。可選引數 startend 的解釋方式與切片表示法相同。失敗時返回 -1

要搜尋的子序列可以是任何 類位元組物件 或 0 到 255 範圍內的整數。

版本 3.3 中已更改: 現在也接受 0 到 255 範圍內的整數作為子序列。

bytes.rindex(sub[, start[, end]])
bytearray.rindex(sub[, start[, end]])

rfind() 類似,但在找不到子序列 sub 時引發 ValueError

要搜尋的子序列可以是任何 類位元組物件 或 0 到 255 範圍內的整數。

版本 3.3 中已更改: 現在也接受 0 到 255 範圍內的整數作為子序列。

bytes.rpartition(sep, /)
bytearray.rpartition(sep, /)

在最後一次出現 sep 的位置拆分序列,並返回一個包含分隔符之前的部分、分隔符本身或其 bytearray 副本以及分隔符之後的部分的 3 元組。如果找不到分隔符,則返回一個包含兩個空 bytes 或 bytearray 物件、後跟原始序列副本的 3 元組。

要搜尋的分隔符可以是任何 類位元組物件

bytes.startswith(prefix[, start[, end]])
bytearray.startswith(prefix[, start[, end]])

如果二進位制資料以指定的 prefix 開頭,則返回 True,否則返回 Falseprefix 也可以是用於查詢的字首元組。使用可選的 start,從該位置開始測試。使用可選的 end,在該位置停止比較。

要搜尋的字首可以是任何 類位元組物件

bytes.translate(table, /, delete=b'')
bytearray.translate(table, /, delete=b'')

返回 bytes 或 bytearray 物件的副本,其中刪除可選引數 delete 中出現的所有位元組,並將剩餘的位元組透過給定的轉換表進行對映,該表必須是長度為 256 的 bytes 物件。

您可以使用 bytes.maketrans() 方法建立轉換表。

table 引數設定為 None 以僅刪除字元的轉換。

>>> b'read this short text'.translate(None, b'aeiou')
b'rd ths shrt txt'

版本 3.6 中已更改: 現在支援 delete 作為關鍵字引數。

bytes 和 bytearray 物件上的以下方法具有預設行為,這些行為假定使用 ASCII 相容的二進位制格式,但透過傳遞適當的引數仍可與任意二進位制資料一起使用。請注意,此部分中的所有 bytearray 方法會就地操作,而是生成新物件。

bytes.center(width, fillbyte=b' ', /)
bytearray.center(width, fillbyte=b' ', /)

返回一個居中於長度為 width 的序列中的物件的副本。填充使用指定的 fillbyte(預設為 ASCII 空格)。對於 bytes 物件,如果 width 小於或等於 len(s),則返回原始序列。

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.ljust(width, fillbyte=b' ', /)
bytearray.ljust(width, fillbyte=b' ', /)

返回一個左對齊於長度為 width 的序列中的物件的副本。填充使用指定的 fillbyte(預設為 ASCII 空格)。對於 bytes 物件,如果 width 小於或等於 len(s),則返回原始序列。

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.lstrip(bytes=None, /)
bytearray.lstrip(bytes=None, /)

返回一個副本,其中刪除了指定的開頭位元組。bytes 引數是一個二進位制序列,指定要刪除的位元組值集合。如果省略或為 None,則 bytes 引數預設為刪除 ASCII 空白字元。bytes 引數不是字首;而是,其所有值的組合都會被刪除。

>>> b'   spacious   '.lstrip()
b'spacious   '
>>> b'www.example.com'.lstrip(b'cmowz.')
b'example.com'

要刪除的位元組值的二進位制序列可以是任何 類位元組物件。有關刪除單個字首字串而不是一組字元的方法,請參閱 removeprefix()。例如:

>>> b'Arthur: three!'.lstrip(b'Arthur: ')
b'ee!'
>>> b'Arthur: three!'.removeprefix(b'Arthur: ')
b'three!'

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.rjust(width, fillbyte=b' ', /)
bytearray.rjust(width, fillbyte=b' ', /)

返回一個右對齊於長度為 width 的序列中的物件的副本。填充使用指定的 fillbyte(預設為 ASCII 空格)。對於 bytes 物件,如果 width 小於或等於 len(s),則返回原始序列。

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.rsplit(sep=None, maxsplit=-1)
bytearray.rsplit(sep=None, maxsplit=-1)

使用 sep 作為分隔符字串,將二進位制序列拆分為相同型別的子序列。如果給出了 maxsplit,則最多執行 maxsplit 次拆分,即最右邊的拆分。如果 sep 未指定或為 None,則任何僅由 ASCII 空白字元組成的子序列都是分隔符。除了從右側拆分外,rsplit() 的行為與下面詳細描述的 split() 相同。

bytes.rstrip(bytes=None, /)
bytearray.rstrip(bytes=None, /)

返回一個副本,其中刪除了指定的結尾位元組。bytes 引數是一個二進位制序列,指定要刪除的位元組值集合。如果省略或為 None,則 bytes 引數預設為刪除 ASCII 空白字元。bytes 引數不是字尾;而是,其所有值的組合都會被刪除。

>>> b'   spacious   '.rstrip()
b'   spacious'
>>> b'mississippi'.rstrip(b'ipz')
b'mississ'

要刪除的位元組值的二進位制序列可以是任何 類位元組物件。有關刪除單個字尾字串而不是一組字元的方法,請參閱 removesuffix()。例如:

>>> b'Monty Python'.rstrip(b' Python')
b'M'
>>> b'Monty Python'.removesuffix(b' Python')
b'Monty'

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.split(sep=None, maxsplit=-1)
bytearray.split(sep=None, maxsplit=-1)

使用 sep 作為分隔符字串,將二進位制序列拆分為相同型別的子序列。如果給出了 maxsplit 且為非負數,則最多執行 maxsplit 次拆分(因此,列表最多包含 maxsplit+1 個元素)。如果未指定 maxsplit 或為 -1,則拆分次數沒有限制(進行所有可能的拆分)。

如果給出了 sep,則連續的分隔符不會合並,並被視為分隔空子序列(例如,b'1,,2'.split(b',') 返回 [b'1', b'', b'2'])。sep 引數可以包含多位元組序列作為單個分隔符。拆分空序列並指定分隔符會返回 [b''][bytearray(b'')],具體取決於要拆分的物件的型別。sep 引數可以是任何 類位元組物件

例如:

>>> b'1,2,3'.split(b',')
[b'1', b'2', b'3']
>>> b'1,2,3'.split(b',', maxsplit=1)
[b'1', b'2,3']
>>> b'1,2,,3,'.split(b',')
[b'1', b'2', b'', b'3', b'']
>>> b'1<>2<>3<4'.split(b'<>')
[b'1', b'2', b'3<4']

如果未指定 sep 或為 None,則應用不同的拆分演算法:連續的 ASCII 空白字元被視為單個分隔符,並且結果不包含開頭或結尾的空字串(如果序列有前導或尾隨空白)。因此,在未指定分隔符的情況下拆分空序列或僅由 ASCII 空白字元組成的序列會返回 []

例如:

>>> b'1 2 3'.split()
[b'1', b'2', b'3']
>>> b'1 2 3'.split(maxsplit=1)
[b'1', b'2 3']
>>> b'   1   2   3   '.split()
[b'1', b'2', b'3']
bytes.strip(bytes=None, /)
bytearray.strip(bytes=None, /)

返回一個副本,其中刪除了指定的開頭和結尾位元組。bytes 引數是一個二進位制序列,指定要刪除的位元組值集合。如果省略或為 None,則 bytes 引數預設為刪除 ASCII 空白字元。bytes 引數不是字首或字尾;而是,其所有值的組合都會被刪除。

>>> b'   spacious   '.strip()
b'spacious'
>>> b'www.example.com'.strip(b'cmowz.')
b'example'

要刪除的位元組值的二進位制序列可以是任何 類位元組物件

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes 和 bytearray 物件上的以下方法假定使用 ASCII 相容的二進位制格式,不應用於處理任意二進位制資料。請注意,此部分中的所有 bytearray 方法會就地操作,而是生成新物件。

bytes.capitalize()
bytearray.capitalize()

返回序列的副本,其中每個位元組都被解釋為 ASCII 字元,第一個位元組大寫,其餘位元組小寫。非 ASCII 位元組值將保持不變。

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.expandtabs(tabsize=8)
bytearray.expandtabs(tabsize=8)

返回序列的副本,其中所有 ASCII 製表符都替換為一個或多個 ASCII 空格,具體取決於當前列和給定的製表符大小。製表符位置每 tabsize 位元組出現一次(預設值為 8,製表符位置在列 0、8、16 等處)。要展開序列,當前列設定為零,然後逐位元組檢查序列。如果該位元組是 ASCII 製表符(b'\t'),則在結果中插入一個或多個空格字元,直到當前列等於下一個製表符位置。(製表符本身不被複制)。如果當前位元組是 ASCII 換行符(b'\n')或回車符(b'\r'),則將其複製,並將當前列重置為零。任何其他位元組值都將保持不變,並且當前列會增加一個,無論該位元組值在列印時如何表示。

>>> b'01\t012\t0123\t01234'.expandtabs()
b'01      012     0123    01234'
>>> b'01\t012\t0123\t01234'.expandtabs(4)
b'01  012 0123    01234'

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.isalnum()
bytearray.isalnum()

如果序列中的所有位元組都是字母 ASCII 字元或 ASCII 十進位制數字,並且序列非空,則返回 True,否則返回 False。字母 ASCII 字元是 b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 序列中的位元組值。ASCII 十進位制數字是 b'0123456789' 序列中的位元組值。

例如:

>>> b'ABCabc1'.isalnum()
True
>>> b'ABC abc1'.isalnum()
False
bytes.isalpha()
bytearray.isalpha()

如果序列中的所有位元組都是字母 ASCII 字元,並且序列非空,則返回 True,否則返回 False。字母 ASCII 字元是 b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 序列中的位元組值。

例如:

>>> b'ABCabc'.isalpha()
True
>>> b'ABCabc1'.isalpha()
False
bytes.isascii()
bytearray.isascii()

如果序列為空或序列中的所有位元組都是 ASCII,則返回 True,否則返回 False。ASCII 位元組的範圍是 0-0x7F。

在 3.7 版本加入。

bytes.isdigit()
bytearray.isdigit()

如果序列中的所有位元組都是 ASCII 十進位制數字,並且序列非空,則返回 True,否則返回 False。ASCII 十進位制數字是 b'0123456789' 序列中的位元組值。

例如:

>>> b'1234'.isdigit()
True
>>> b'1.23'.isdigit()
False
bytes.islower()
bytearray.islower()

如果序列中至少有一個小寫 ASCII 字元且沒有大寫 ASCII 字元,則返回 True,否則返回 False

例如:

>>> b'hello world'.islower()
True
>>> b'Hello world'.islower()
False

小寫 ASCII 字元是 b'abcdefghijklmnopqrstuvwxyz' 序列中的位元組值。大寫 ASCII 字元是 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 序列中的位元組值。

bytes.isspace()
bytearray.isspace()

如果序列中的所有位元組都是 ASCII 空白字元,並且序列非空,則返回 True,否則返回 False。ASCII 空白字元是 b' \t\n\r\x0b\f'(空格、製表符、換行符、回車符、垂直製表符、換頁符)序列中的位元組值。

bytes.istitle()
bytearray.istitle()

如果序列是 ASCII 標題化且序列非空,則返回 True,否則返回 False。有關“標題化”的定義,請參閱 bytes.title()

例如:

>>> b'Hello World'.istitle()
True
>>> b'Hello world'.istitle()
False
bytes.isupper()
bytearray.isupper()

如果序列中至少有一個大寫 ASCII 字母字元且沒有小寫 ASCII 字元,則返回 True,否則返回 False

例如:

>>> b'HELLO WORLD'.isupper()
True
>>> b'Hello world'.isupper()
False

小寫 ASCII 字元是 b'abcdefghijklmnopqrstuvwxyz' 序列中的位元組值。大寫 ASCII 字元是 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 序列中的位元組值。

bytes.lower()
bytearray.lower()

返回序列的副本,其中所有大寫 ASCII 字元都轉換為相應的小寫字元。

例如:

>>> b'Hello World'.lower()
b'hello world'

小寫 ASCII 字元是 b'abcdefghijklmnopqrstuvwxyz' 序列中的位元組值。大寫 ASCII 字元是 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 序列中的位元組值。

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.splitlines(keepends=False)
bytearray.splitlines(keepends=False)

返回二進位制序列中的行的列表,在 ASCII 行邊界處斷開。此方法使用 通用換行符 方法拆分行。除非給定了 keepends 且為 true,否則行結尾符不包含在結果列表中。

例如:

>>> b'ab c\n\nde fg\rkl\r\n'.splitlines()
[b'ab c', b'', b'de fg', b'kl']
>>> b'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True)
[b'ab c\n', b'\n', b'de fg\r', b'kl\r\n']

與給出分隔符字串 sep 時的 split() 不同,此方法對於空字串返回空列表,並且尾部換行符不會導致產生額外的行。

>>> b"".split(b'\n'), b"Two lines\n".split(b'\n')
([b''], [b'Two lines', b''])
>>> b"".splitlines(), b"One line\n".splitlines()
([], [b'One line'])
bytes.swapcase()
bytearray.swapcase()

返回序列的副本,其中所有小寫 ASCII 字元都轉換為相應的大寫字元,反之亦然。

例如:

>>> b'Hello World'.swapcase()
b'hELLO wORLD'

小寫 ASCII 字元是 b'abcdefghijklmnopqrstuvwxyz' 序列中的位元組值。大寫 ASCII 字元是 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 序列中的位元組值。

str.swapcase() 不同,對於二進位制版本,始終有 bin.swapcase().swapcase() == bin。ASCII 中的大小寫轉換是雙向的,即使這對於任意 Unicode 程式碼點通常不成立。

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.title()
bytearray.title()

返回二進位制序列的標題化版本,其中單詞以大寫 ASCII 字元開頭,其餘字元為小寫。未區分大小寫的位元組值保持不變。

例如:

>>> b'Hello world'.title()
b'Hello World'

小寫 ASCII 字元是 b'abcdefghijklmnopqrstuvwxyz' 序列中的位元組值。大寫 ASCII 字元是 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 序列中的位元組值。所有其他位元組值均未區分大小寫。

該演算法使用一種簡單的、與語言無關的單詞定義,即將單詞定義為連續字母的組。該定義在許多情況下都有效,但這意味著縮寫和所有格中的撇號會形成單詞邊界,這可能不是期望的結果。

>>> b"they're bill's friends from the UK".title()
b"They'Re Bill'S Friends From The Uk"

可以使用正則表示式構造一個解決撇號問題的變通方法。

>>> import re
>>> def titlecase(s):
...     return re.sub(rb"[A-Za-z]+('[A-Za-z]+)?",
...                   lambda mo: mo.group(0)[0:1].upper() +
...                              mo.group(0)[1:].lower(),
...                   s)
...
>>> titlecase(b"they're bill's friends.")
b"They're Bill's Friends."

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.upper()
bytearray.upper()

返回序列的副本,其中所有小寫 ASCII 字元都轉換為相應的大寫字元。

例如:

>>> b'Hello World'.upper()
b'HELLO WORLD'

小寫 ASCII 字元是 b'abcdefghijklmnopqrstuvwxyz' 序列中的位元組值。大寫 ASCII 字元是 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 序列中的位元組值。

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

bytes.zfill(width, /)
bytearray.zfill(width, /)

返回序列的副本,在左側用 ASCII b'0' 數字填充,使其長度為 width。前導符號(b'+'/ b'-')會被處理,將填充插入到符號字元之後而不是之前。對於 bytes 物件,如果 width 小於或等於 len(seq),則返回原始序列。

例如:

>>> b"42".zfill(5)
b'00042'
>>> b"-42".zfill(5)
b'-0042'

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

printf 風格的位元組格式化

備註

此處描述的格式化操作會顯示各種怪癖,導致一些常見錯誤(例如,未能正確顯示元組和字典)。如果列印的值可能是元組或字典,請將其包裝在元組中。

Bytes 物件(bytes/bytearray)有一個獨特的內建操作:% 運算子(模運算子)。這也被稱為位元組格式化插值運算子。給定 format % values(其中 format 是一個 bytes 物件),format 中的 % 轉換說明符會被 values 的零個或多個元素替換。效果類似於 C 語言中的 sprintf()

如果 format 需要單個引數,values 可以是單個非元組物件。[5] 否則,values 必須是一個元組,其元素數量與格式 bytes 物件指定的數量完全一致,或者是一個單獨的對映物件(例如,字典)。

轉換規範包含兩個或更多個字元,並具有以下組成部分,它們必須按此順序出現:

  1. 標記規範開頭的'%'字元。

  2. 對映鍵(可選),由一系列括號括起來的字元組成(例如,(somename))。

  3. 轉換標誌(可選),它們會影響某些轉換型別的結果。

  4. 最小欄位寬度(可選)。如果指定為'*'(星號),則實際寬度將從values中的下一個元素讀取,要轉換的物件將出現在最小欄位寬度和可選精度之後。

  5. 精度(可選),給出為'.'(點)後跟精度。如果指定為'*'(星號),則實際精度將從values中的下一個元素讀取,要轉換的值將出現在精度之後。

  6. 長度修改符(可選)。

  7. 轉換型別。

當右側引數是字典(或其他對映型別)時,bytes 物件中的格式必須包含一個括號括起來的字典鍵,緊跟在 '%' 字元之後。對映鍵從對映中選擇要格式化的值。例如:

>>> print(b'%(language)s has %(number)03d quote types.' %
...       {b'language': b"Python", b"number": 2})
b'Python has 002 quote types.'

在這種情況下,格式中可能不會出現*規範(因為它們需要順序引數列表)。

轉換標誌字元是:

Flag

含義

'#'

轉換將使用“備用形式”(如下定義)。

'0'

對於數字值,轉換將使用零填充。

'-'

轉換將左對齊(如果兩者都給出,則覆蓋'0'轉換)。

' '

(空格)在有符號轉換產生的正數(或空字串)之前應留有一個空格。

'+'

符號字元('+''-')將出現在轉換之前(覆蓋“空格”標誌)。

長度修改符(h, l, 或 L)可能存在,但在 Python 中被忽略,因為它們不是必需的——所以例如%ld%d相同。

轉換型別是:

轉換

含義

備註

'd'

帶符號整數十進位制。

'i'

帶符號整數十進位制。

'o'

帶符號八進位制值。

(1)

'u'

已棄用的型別——它與'd'相同。

(8)

'x'

帶符號十六進位制(小寫)。

(2)

'X'

帶符號十六進位制(大寫)。

(2)

'e'

浮點指數格式(小寫)。

(3)

'E'

浮點指數格式(大寫)。

(3)

'f'

浮點十進位制格式。

(3)

'F'

浮點十進位制格式。

(3)

'g'

浮點格式。當指數小於 -4 或不小於精度時,使用小寫指數格式,否則使用十進位制格式。

(4)

'G'

浮點格式。當指數小於 -4 或不小於精度時,使用大寫指數格式,否則使用十進位制格式。

(4)

'c'

單個位元組(接受整數或單個位元組物件)。

'b'

位元組(任何遵循 緩衝區協議 或具有 __bytes__() 的物件)。

(5)

's'

's''b' 的別名,應僅用於 Python2/3 程式碼庫。

(6)

'a'

位元組(使用 repr(obj).encode('ascii', 'backslashreplace') 將任何 Python 物件轉換為位元組)。

(5)

'r'

'r''a' 的別名,應僅用於 Python2/3 程式碼庫。

(7)

'%'

不轉換引數,結果中產生一個'%'字元。

備註

  1. 備用形式會在第一個數字之前插入一個前導八進位制說明符('0o')。

  2. 備用形式會在第一個數字之前插入一個前導'0x''0X'(取決於使用的是'x'還是'X'格式)。

  3. 備用形式會導致結果始終包含小數點,即使小數點後面沒有數字。

    精度決定小數點後的位數,預設為 6。

  4. 備用形式會導致結果始終包含小數點,並且尾隨零不會像通常那樣被刪除。

    精度決定小數點前後有效數字的位數,預設為 6。

  5. 如果精度為N,則輸出將截斷為N個字元。

  6. b'%s' 已棄用,但在 3.x 系列中不會被移除。

  7. b'%r' 已棄用,但在 3.x 系列中不會被移除。

  8. 請參閱 PEP 237

備註

此方法的 bytearray 版本會就地操作 - 它始終生成新物件,即使未進行任何更改。

參見

PEP 461 - 為 bytes 和 bytearray 新增 % 格式化。

在 3.5 版本加入。

記憶體檢視

memoryview 物件允許 Python 程式碼在不復制的情況下訪問支援 緩衝區協議 的物件的內部資料。

class memoryview(object)

建立引用 objectmemoryviewobject 必須支援緩衝區協議。內建物件,如 bytesbytearray,都支援緩衝區協議。

memoryview 具有元素的概念,它是起源物件處理的原子記憶體單元。對於像 bytesbytearray 這樣的許多簡單型別,一個元素是單個位元組,但像 array.array 這樣的其他型別可能具有更大的元素。

len(view) 等於 tolist 的長度,這是檢視的巢狀列表表示。如果 view.ndim = 1,則它等於檢視中的元素數。

版本 3.12 中已更改: 如果 view.ndim == 0len(view) 現在會引發 TypeError 而不是返回 1。

itemsize 屬性將為您提供單個元素的位元組數。

memoryview 支援切片和索引來暴露其資料。一維切片將生成子檢視。

>>> v = memoryview(b'abcefg')
>>> v[1]
98
>>> v[-1]
103
>>> v[1:4]
<memory at 0x7f3ddc9f4350>
>>> bytes(v[1:4])
b'bce'

如果 formatstruct 模組中的原生格式說明符之一,則使用整數或整數元組進行索引也受支援,並返回具有正確型別的單個元素。一維 memoryview 可以用整數或單整數元組索引。多維 memoryview 可以用恰好包含 ndim 個整數的元組索引,其中 ndim 是維度的數量。零維 memoryview 可以用空元組索引。

這是一個具有非位元組格式的示例:

>>> import array
>>> a = array.array('l', [-11111111, 22222222, -33333333, 44444444])
>>> m = memoryview(a)
>>> m[0]
-11111111
>>> m[-1]
44444444
>>> m[::2].tolist()
[-11111111, -33333333]

如果底層物件是可寫的,則 memoryview 支援一維切片賦值。不允許調整大小。

>>> data = bytearray(b'abcefg')
>>> v = memoryview(data)
>>> v.readonly
False
>>> v[0] = ord(b'z')
>>> data
bytearray(b'zbcefg')
>>> v[1:4] = b'123'
>>> data
bytearray(b'z123fg')
>>> v[2:3] = b'spam'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: memoryview assignment: lvalue and rvalue have different structures
>>> v[2:6] = b'spam'
>>> data
bytearray(b'z1spam')

格式為“B”、“b”或“c”的可雜湊(只讀)型別的單位元組 memoryview 也可雜湊。雜湊定義為 hash(m) == hash(m.tobytes())

>>> v = memoryview(b'abcefg')
>>> hash(v) == hash(b'abcefg')
True
>>> hash(v[2:4]) == hash(b'ce')
True
>>> hash(v[::-2]) == hash(b'abcefg'[::-2])
True

版本 3.3 中已更改: 現在可以對一維 memoryview 進行切片。格式為“B”、“b”或“c”的一維 memoryview 現在是可雜湊的。

版本 3.4 中已更改: memoryview 現在已自動註冊到 collections.abc.Sequence

版本 3.5 中已更改: memoryview 現在可以用整數元組進行索引。

版本 3.14 中已更改: memoryview 現在是泛型型別

memoryview 有幾個方法:

__eq__(exporter)

當使用 struct 語法解釋各自的格式程式碼時,如果 memoryview 和 PEP 3118 匯出器具有等效的形狀且所有對應值相等,則它們相等。

對於目前 tolist() 支援的 struct 格式字串的子集,vw 相等,當且僅當 v.tolist() == w.tolist()

>>> import array
>>> a = array.array('I', [1, 2, 3, 4, 5])
>>> b = array.array('d', [1.0, 2.0, 3.0, 4.0, 5.0])
>>> c = array.array('b', [5, 3, 1])
>>> x = memoryview(a)
>>> y = memoryview(b)
>>> x == a == y == b
True
>>> x.tolist() == a.tolist() == y.tolist() == b.tolist()
True
>>> z = y[::-2]
>>> z == c
True
>>> z.tolist() == c.tolist()
True

如果任一格式字串不受 struct 模組支援,則物件將始終比較為不相等(即使格式字串和緩衝區內容相同)。

>>> from ctypes import BigEndianStructure, c_long
>>> class BEPoint(BigEndianStructure):
...     _fields_ = [("x", c_long), ("y", c_long)]
...
>>> point = BEPoint(100, 200)
>>> a = memoryview(point)
>>> b = memoryview(point)
>>> a == point
False
>>> a == b
False

請注意,與浮點數一樣,v is w 對於 memoryview 物件意味著 v == w

版本 3.3 中已更改: 以前的版本會忽略專案格式和邏輯陣列結構,直接比較原始記憶體。

tobytes(order='C')

返回緩衝區中的資料作為位元組字串。這相當於在 memoryview 上呼叫 bytes 建構函式。

>>> m = memoryview(b"abc")
>>> m.tobytes()
b'abc'
>>> bytes(m)
b'abc'

對於非連續陣列,結果等於所有元素轉換為位元組的展平列表表示。tobytes() 支援所有格式字串,包括 struct 模組語法中不包含的格式字串。

版本 3.8 中已新增: order 可以是 {‘C’, ‘F’, ‘A’}。當 order 為 ‘C’ 或 ‘F’ 時,原始陣列的資料被轉換為 C 或 Fortran 順序。對於連續檢視,‘A’ 返回物理記憶體的精確副本。特別地,記憶體中的 Fortran 順序被保留。對於非連續檢視,資料首先被轉換為 C。order=Noneorder=’C’ 相同。

hex(*, bytes_per_sep=1)
hex(sep, bytes_per_sep=1)

返回一個字串物件,其中緩衝區中的每個位元組都用兩個十六進位制數字表示。

>>> m = memoryview(b"abc")
>>> m.hex()
'616263'

在 3.5 版本加入。

版本 3.8 中已更改: 類似於 bytes.hex()memoryview.hex() 現在支援可選的 sepbytes_per_sep 引數,用於在十六進位制輸出的位元組之間插入分隔符。

tolist()

返回緩衝區中的資料作為元素列表。

>>> memoryview(b'abc').tolist()
[97, 98, 99]
>>> import array
>>> a = array.array('d', [1.1, 2.2, 3.3])
>>> m = memoryview(a)
>>> m.tolist()
[1.1, 2.2, 3.3]

版本 3.3 中已更改: tolist() 現在支援 struct 模組語法中的所有單字元原生格式以及多維表示。

toreadonly()

返回 memoryview 物件的只讀版本。原始 memoryview 物件保持不變。

>>> m = memoryview(bytearray(b'abc'))
>>> mm = m.toreadonly()
>>> mm.tolist()
[97, 98, 99]
>>> mm[0] = 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot modify read-only memory
>>> m[0] = 43
>>> mm.tolist()
[43, 98, 99]

在 3.8 版本加入。

release()

釋放 memoryview 物件公開的底層緩衝區。許多物件在對其持有檢視時會採取特殊操作(例如,bytearray 會暫時禁止調整大小);因此,呼叫 release() 方法有助於儘快刪除這些限制(並釋放任何懸空資源)。

呼叫此方法後,對檢視的任何後續操作都會引發 ValueError(除了 release() 本身,它可以被多次呼叫)。

>>> m = memoryview(b'abc')
>>> m.release()
>>> m[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operation forbidden on released memoryview object

上下文管理協議可以使用 with 語句實現類似的效果。

>>> with memoryview(b'abc') as m:
...     m[0]
...
97
>>> m[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operation forbidden on released memoryview object

在 3.2 版本加入。

cast(format, /)
cast(format, shape, /)

將 memoryview 轉換為新的格式或形狀。shape 的預設值是 [byte_length//new_itemsize],這意味著結果檢視將是一維的。返回值是一個新的 memoryview,但緩衝區本身不會被複制。支援的轉換包括 1D -> C-contiguous 和 C-contiguous -> 1D。

目標格式僅限於 struct 語法中的單個元素本機格式。其中一種格式必須是位元組格式(“B”、“b”或“c”)。結果的位元組長度必須與原始長度相同。請注意,所有位元組長度可能取決於作業系統。

將 1D/long 轉換為 1D/unsigned bytes

>>> import array
>>> a = array.array('l', [1,2,3])
>>> x = memoryview(a)
>>> x.format
'l'
>>> x.itemsize
8
>>> len(x)
3
>>> x.nbytes
24
>>> y = x.cast('B')
>>> y.format
'B'
>>> y.itemsize
1
>>> len(y)
24
>>> y.nbytes
24

將 1D/unsigned bytes 轉換為 1D/char

>>> b = bytearray(b'zyz')
>>> x = memoryview(b)
>>> x[0] = b'a'
Traceback (most recent call last):
  ...
TypeError: memoryview: invalid type for format 'B'
>>> y = x.cast('c')
>>> y[0] = b'a'
>>> b
bytearray(b'ayz')

將 1D/bytes 轉換為 3D/ints,再轉換為 1D/signed char

>>> import struct
>>> buf = struct.pack("i"*12, *list(range(12)))
>>> x = memoryview(buf)
>>> y = x.cast('i', shape=[2,2,3])
>>> y.tolist()
[[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]]
>>> y.format
'i'
>>> y.itemsize
4
>>> len(y)
2
>>> y.nbytes
48
>>> z = y.cast('b')
>>> z.format
'b'
>>> z.itemsize
1
>>> len(z)
48
>>> z.nbytes
48

將 1D/unsigned long 轉換為 2D/unsigned long

>>> buf = struct.pack("L"*6, *list(range(6)))
>>> x = memoryview(buf)
>>> y = x.cast('L', shape=[2,3])
>>> len(y)
2
>>> y.nbytes
48
>>> y.tolist()
[[0, 1, 2], [3, 4, 5]]

在 3.3 版本加入。

版本 3.5 中已更改: 在轉換為位元組檢視時,源格式不再受限制。

count(value, /)

計算 value 出現的次數。

在 3.14 版本加入。

index(value, start=0, stop=sys.maxsize, /)

返回 value 第一次出現(在索引 start 或之後,在索引 stop 之前)的索引。

如果找不到 value,則引發 ValueError

在 3.14 版本加入。

還有一些只讀屬性可用

obj

memoryview 的底層物件

>>> b  = bytearray(b'xyz')
>>> m = memoryview(b)
>>> m.obj is b
True

在 3.3 版本加入。

nbytes

nbytes == product(shape) * itemsize == len(m.tobytes())。這是陣列在連續表示中使用的大小(以位元組為單位)。它不一定等於 len(m)

>>> import array
>>> a = array.array('i', [1,2,3,4,5])
>>> m = memoryview(a)
>>> len(m)
5
>>> m.nbytes
20
>>> y = m[::2]
>>> len(y)
3
>>> y.nbytes
12
>>> len(y.tobytes())
12

多維陣列

>>> import struct
>>> buf = struct.pack("d"*12, *[1.5*x for x in range(12)])
>>> x = memoryview(buf)
>>> y = x.cast('d', shape=[3,4])
>>> y.tolist()
[[0.0, 1.5, 3.0, 4.5], [6.0, 7.5, 9.0, 10.5], [12.0, 13.5, 15.0, 16.5]]
>>> len(y)
3
>>> y.nbytes
96

在 3.3 版本加入。

readonly

一個布林值,指示記憶體是否只讀。

format

一個字串,包含檢視中每個元素的格式(採用 struct 模組風格)。Memoryview 可以從具有任意格式字串的匯出器建立,但某些方法(例如 tolist())僅限於本機單個元素格式。

版本 3.3 中已更改: 格式 'B' 現在根據 struct 模組語法進行處理。這意味著 memoryview(b'abc')[0] == b'abc'[0] == 97

itemsize

memoryview 中每個元素的大小(以位元組為單位)

>>> import array, struct
>>> m = memoryview(array.array('H', [32000, 32001, 32002]))
>>> m.itemsize
2
>>> m[0]
32000
>>> struct.calcsize('H') == m.itemsize
True
ndim

一個整數,指示記憶體表示的多維陣列的維數。

shape

一個整數元組,其長度與 ndim 相同,表示記憶體作為 N 維陣列的形狀。

版本 3.3 中已更改: 當 ndim = 0 時,返回空元組而不是 None

strides

一個整數元組,其長度與 ndim 相同,表示陣列每個維度中訪問每個元素的位元組大小。

版本 3.3 中已更改: 當 ndim = 0 時,返回空元組而不是 None

suboffsets

內部用於 PIL 風格的陣列。此值僅供參考。

c_contiguous

一個布林值,指示記憶體是否為 C-contiguous

在 3.3 版本加入。

f_contiguous

一個布林值,指示記憶體是否為 Fortran contiguous

在 3.3 版本加入。

contiguous

一個布林值,指示記憶體是否為contiguous

在 3.3 版本加入。

Set 型別 — set, frozenset

Set 物件是無序的、不重複的、可雜湊物件的集合。常見用途包括成員資格測試、從序列中刪除重複項以及計算交集、並集、差集和對稱差集等數學運算。(有關其他容器,請參閱內建的 dictlisttuple 類,以及 collections 模組。)

與所有集合一樣,集合支援 x in setlen(set)for x in set。由於是無序集合,集合不記錄元素位置或插入順序。因此,集合不支援索引、切片或其他類序列行為。

目前有兩種內建的集合型別:setfrozensetset 型別是可變的——內容可以透過 add()remove() 等方法進行更改。由於它是可變的,因此沒有雜湊值,不能用作字典鍵或另一個集合的元素。frozenset 型別是不可變的且可雜湊——建立後其內容無法更改;因此,它可以作為字典鍵或另一個集合的元素。

非空集合(非 frozensets)可以透過將逗號分隔的元素列表放在大括號內建立,例如:{'jack', 'sjoerd'},這是一種除了 set 建構函式之外的建立方式。

兩個類的建構函式工作方式相同

class set(iterable=(), /)
class frozenset(iterable=(), /)

返回一個新的 set 或 frozenset 物件,其元素來自 iterable。set 的元素必須是可雜湊的。要表示集合的集合,內部集合必須是 frozenset 物件。如果未指定 iterable,則返回一個空 set。

Set 可透過多種方式建立

  • 使用大括號內的逗號分隔的元素列表:{'jack', 'sjoerd'}

  • 使用 set 推導式:{c for c in 'abracadabra' if c not in 'abc'}

  • 使用型別建構函式:set(), set('foobar'), set(['a', 'b', 'foo'])

setfrozenset 的例項提供以下操作

len(s)

返回集合 s 中的元素數量(s 的基數)。

x in s

測試 x 是否為 s 的成員。

x not in s

測試 x 是否不是 s 的成員。

isdisjoint(other, /)

如果集合與 other 沒有共同的元素,則返回 True。當且僅當它們的交集為空集時,集合才是不相交的。

issubset(other, /)
set <= other

測試集合中的每個元素是否都在 other 中。

set < other

測試集合是否是 other 的真子集,即 set <= other and set != other

issuperset(other, /)
set >= other

測試 other 中的每個元素是否都在集合中。

set > other

測試集合是否是 other 的真超集,即 set >= other and set != other

union(*others)
set | other | ...

返回一個包含來自集合和所有其他集合的元素的新集合。

intersection(*others)
set & other & ...

返回一個包含來自集合和所有其他集合的共有元素的的新集合。

difference(*others)
set - other - ...

返回一個包含來自集合但不在其他集合中的元素的新集合。

symmetric_difference(other, /)
set ^ other

返回一個包含僅存在於集合或 other 中但不同時存在於兩者的元素的新集合。

copy()

返回集合的淺複製。

注意,非運算子版本的 union()intersection()difference()symmetric_difference()issubset()issuperset() 方法將接受任何可迭代物件作為引數。相比之下,它們的基於運算子的對應項要求其引數為集合。這避免了容易出錯的構造,如 set('abc') & 'cbs',而是使用更具可讀性的 set('abc').intersection('cbs')

setfrozenset 都支援集合到集合的比較。兩個集合相等當且僅當每個集合的元素都包含在另一個集合中(每個集合是另一個集合的子集)。一個集合小於另一個集合當且僅當第一個集合是第二個集合的真子集(是子集,但不是相等)。一個集合大於另一個集合當且僅當第一個集合是第二個集合的真超集(是超集,但不是相等)。

set 的例項與 frozenset 的例項基於它們的成員進行比較。例如,set('abc') == frozenset('abc') 返回 Trueset('abc') in set([frozenset('abc')]) 也返回 True

子集和相等比較不適用於總序函式。例如,任何兩個非空不相交的集合都不相等,並且互不為子集,因此所有以下項都返回 Falsea<ba==ba>b

由於集合只定義了偏序(子集關係),因此 list.sort() 方法對集合列表的輸出是未定義的。

集合元素,如同字典鍵一樣,必須是可雜湊的。

混合 set 例項和 frozenset 的二進位制操作返回第一個運算元的型別。例如:frozenset('ab') | set('bc') 返回 frozenset 的例項。

下表列出了 set 支援的、但不可用於 frozenset 不可變例項的操作

update(*others)
set |= other | ...

更新集合,新增來自所有其他集合的元素。

intersection_update(*others)
set &= other & ...

更新集合,僅保留在集合本身和所有其他集合中找到的元素。

difference_update(*others)
set -= other | ...

更新集合,刪除在其他集合中找到的元素。

symmetric_difference_update(other, /)
set ^= other

更新集合,僅保留存在於任一集合中但不同時存在於兩者的元素。

add(elem, /)

將元素 elem 新增到集合中。

remove(elem, /)

從集合中刪除元素 elem。如果 elem 不在集合中,則引發 KeyError

discard(elem, /)

如果元素 elem 存在,則從集合中刪除它。

pop()

從集合中刪除並返回一個任意元素。如果集合為空,則引發 KeyError

clear()

從集合中刪除所有元素。

注意,非運算子版本的 update()intersection_update()difference_update()symmetric_difference_update() 方法將接受任何可迭代物件作為引數。

注意,__contains__()remove()discard() 方法的 elem 引數可以是集合。為了支援搜尋等效的 frozenset,會從 elem 建立一個臨時的 frozenset。

Mapping 型別 — dict

Mapping 物件將可雜湊值對映到任意物件。Mappings 是可變物件。目前只有一個標準的 mapping 型別,即字典。(有關其他容器,請參閱內建的 listsettuple 類,以及 collections 模組。)

字典的鍵是*幾乎*任意值。不可雜湊的值,即包含列表、字典或其他可變型別(按值而不是按物件身份比較)的值,不能用作鍵。值相等(例如 11.0True)可以互換使用來索引同一個字典條目。

class dict(**kwargs)
class dict(mapping, /, **kwargs)
class dict(iterable, /, **kwargs)

返回一個由可選位置引數和可能為空的關鍵字引數集初始化的新字典。

字典可透過多種方式建立

  • 使用大括號內的逗號分隔的 key: value 對列表:{'jack': 4098, 'sjoerd': 4127}{4098: 'jack', 4127: 'sjoerd'}

  • 使用 dict 推導式:{}, {x: x ** 2 for x in range(10)}

  • 使用型別建構函式:dict(), dict([('foo', 100), ('bar', 200)]), dict(foo=100, bar=200)

如果未提供位置引數,則建立一個空字典。如果提供了位置引數並且它定義了 keys() 方法,則透過使用該方法返回的每個鍵呼叫引數的 __getitem__() 來建立字典。否則,位置引數必須是一個可迭代物件。可迭代物件的每個項本身必須是一個只包含兩個元素的 iterable。每個項的第一個元素成為新字典中的鍵,第二個元素成為相應的值。如果一個鍵出現多次,該鍵的最後一個值將成為新字典中的相應值。

如果提供了關鍵字引數,則將關鍵字引數及其值新增到由位置引數建立的字典中。如果要新增的鍵已存在,則關鍵字引數的值將替換來自位置引數的值。

提供關鍵字引數(如第一個示例所示)僅適用於有效的 Python 識別符號作為鍵的情況。否則,可以使用任何有效的鍵。

字典當且僅當它們具有相同的 (key, value) 對時才相等(忽略順序)。順序比較(‘<’, ‘<=’, ‘>=’, ‘>’)會引發 TypeError。為了說明字典建立和相等性,以下所有示例都返回一個與 {"one": 1, "two": 2, "three": 3} 相等的字典

>>> a = dict(one=1, two=2, three=3)
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
>>> d = dict([('two', 2), ('one', 1), ('three', 3)])
>>> e = dict({'three': 3, 'one': 1, 'two': 2})
>>> f = dict({'one': 1, 'three': 3}, two=2)
>>> a == b == c == d == e == f
True

提供關鍵字引數(如第一個示例所示)僅適用於有效的 Python 識別符號作為鍵的情況。否則,可以使用任何有效的鍵。

字典保留插入順序。請注意,更新鍵不會影響順序。刪除後新增的鍵會插入到末尾。

>>> d = {"one": 1, "two": 2, "three": 3, "four": 4}
>>> d
{'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> list(d)
['one', 'two', 'three', 'four']
>>> list(d.values())
[1, 2, 3, 4]
>>> d["one"] = 42
>>> d
{'one': 42, 'two': 2, 'three': 3, 'four': 4}
>>> del d["two"]
>>> d["two"] = None
>>> d
{'one': 42, 'three': 3, 'four': 4, 'two': None}

版本 3.7 中已更改: 字典順序保證為插入順序。此行為是 CPython 從 3.6 開始的實現細節。

以下是字典支援的操作(因此,自定義對映型別也應支援這些操作)

list(d)

返回字典 d 中所有鍵的列表。

len(d)

返回字典 d 中的項數。

d[key]

返回 d 中鍵為 key 的項。如果 key 不在對映中,則引發 KeyError

如果 dict 的子類定義了 __missing__() 方法且 key 不存在,則 d[key] 操作將使用鍵 key 作為引數呼叫該方法。然後 d[key] 操作返回或引發 __missing__(key) 呼叫所返回或引發的任何內容。沒有其他操作或方法會呼叫 __missing__()。如果未定義 __missing__(),則引發 KeyError__missing__() 必須是一個方法;它不能是例項變數。

>>> class Counter(dict):
...     def __missing__(self, key):
...         return 0
...
>>> c = Counter()
>>> c['red']
0
>>> c['red'] += 1
>>> c['red']
1

上面的示例顯示了 collections.Counter 實現的一部分。另一個 __missing__() 方法由 collections.defaultdict 使用。

d[key] = value

d[key] 設定為 value

del d[key]

d 中刪除 d[key]。如果 key 不在對映中,則引發 KeyError

key in d

如果 d 有鍵 key,則返回 True,否則返回 False

key not in d

等同於 not key in d

iter(d)

返回字典鍵的迭代器。這是 iter(d.keys()) 的快捷方式。

clear()

從字典中刪除所有項。

copy()

返回字典的淺複製。

classmethod fromkeys(iterable, value=None, /)

建立一個新的字典,其鍵來自 iterable,值設定為 value

fromkeys() 是一個類方法,它返回一個新字典。value 的預設值為 None。所有值都指向單個例項,因此 value 是可變物件(如空列表)通常沒有意義。要獲得不同的值,請改用 dict 推導式

get(key, default=None, /)

如果 key 在字典中,則返回其值;否則返回 default。如果未提供 default,則預設值為 None,因此此方法永遠不會引發 KeyError

items()

返回字典項((key, value) 對)的新檢視。請參閱檢視物件文件

keys()

返回字典鍵的新檢視。請參閱檢視物件文件

pop(key, /)
pop(key, default, /)

如果 key 在字典中,則刪除它並返回其值;否則返回 default。如果未提供 defaultkey 不在字典中,則引發 KeyError

popitem()

從字典中刪除並返回一個 (key, value) 對。對按 LIFO 順序返回。

popitem() 對於破壞性地迭代字典很有用,如集合演算法中常用的那樣。如果字典為空,呼叫 popitem() 會引發 KeyError

版本 3.7 中已更改: LIFO 順序現在已保證。在先前版本中,popitem() 會返回一個任意的鍵/值對。

reversed(d)

返回字典鍵的反向迭代器。這是 reversed(d.keys()) 的快捷方式。

在 3.8 版本加入。

setdefault(key, default=None, /)

如果 key 在字典中,則返回其值。如果不在,則插入 key,值為 default,並返回 defaultdefault 預設為 None

update(**kwargs)
update(mapping, /, **kwargs)
update(iterable, /, **kwargs)

使用來自 mappingiterablekwargs 的鍵/值對更新字典,覆蓋現有鍵。返回 None

update() 接受帶有 keys() 方法的另一個物件(在這種情況下,將使用從方法返回的每個鍵呼叫 __getitem__())或鍵/值對的可迭代物件(作為元組或其他長度為二的 iterable)。如果指定了關鍵字引數,則字典隨後將使用這些鍵/值對進行更新:d.update(red=1, blue=2)

values()

返回字典值的檢視。請參閱檢視物件文件

一個 dict.values() 檢視與另一個檢視之間的相等性比較將始終返回 False。這也適用於將 dict.values() 與自身進行比較的情況。

>>> d = {'a': 1}
>>> d.values() == d.values()
False
d | other

建立一個新字典,其中包含 dother 的合併鍵值對,兩者都必須是字典。當 dother 共享鍵時,other 的值具有優先權。

在 3.9 版本中新增。

d |= other

使用 other 的鍵和值更新字典 dother 可以是 mapping 或鍵/值對的 iterable。當 dother 共享鍵時,other 的值具有優先權。

在 3.9 版本中新增。

字典和字典檢視是可逆的。

>>> d = {"one": 1, "two": 2, "three": 3, "four": 4}
>>> d
{'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> list(reversed(d))
['four', 'three', 'two', 'one']
>>> list(reversed(d.values()))
[4, 3, 2, 1]
>>> list(reversed(d.items()))
[('four', 4), ('three', 3), ('two', 2), ('one', 1)]

版本 3.8 中已更改: 字典現在是可逆的。

參見

types.MappingProxyType 可用於建立 dict 的只讀檢視。

字典檢視物件

dict.keys()dict.values()dict.items() 返回的物件是*檢視物件*。它們提供對字典條目的動態檢視,這意味著當字典發生變化時,檢視會反映這些變化。

字典檢視可以迭代以產生各自的資料,並且支援成員資格測試

len(dictview)

返回字典中的條目數。

iter(dictview)

返回字典的鍵、值或項(表示為 (key, value) 元組)的迭代器。

鍵和值按插入順序迭代。這允許使用 zip() 建立 (value, key) 對:pairs = zip(d.values(), d.keys())。建立相同列表的另一種方法是 pairs = [(v, k) for (k, v) in d.items()]

在迭代檢視時新增或刪除字典中的條目可能會引發 RuntimeError 或未能迭代所有條目。

版本 3.7 中已更改: 字典順序保證為插入順序。

x in dictview

如果 x 存在於底層字典的鍵、值或項中(在後一種情況下,x 應為 (key, value) 元組),則返回 True

reversed(dictview)

返回字典的鍵、值或項的反向迭代器。檢視將按插入順序的反向迭代。

版本 3.8 中已更改: 字典檢視現在是可逆的。

dictview.mapping

返回一個 types.MappingProxyType,它包裝了檢視引用的原始字典。

在 3.10 版本加入。

鍵檢視是類似集合的,因為它們的條目是唯一的且可雜湊的。項檢視也具有類似集合的操作,因為 (key, value) 對是唯一的且鍵是可雜湊的。如果項檢視中的所有值也都是可雜湊的,那麼項檢視就可以與其他集合進行互操作。(值檢視不被視為類似集合的,因為其中的條目通常不是唯一的。)對於類似集合的檢視,抽象基類 collections.abc.Set 中定義的所有操作(例如,==<^)都可用。(在使用集合運算子時,類似集合的檢視接受任何可迭代物件作為另一個運算元,而集合只接受集合作為輸入。)

字典檢視使用的示例

>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.keys()
>>> values = dishes.values()

>>> # iteration
>>> n = 0
>>> for val in values:
...     n += val
...
>>> print(n)
504

>>> # keys and values are iterated over in the same order (insertion order)
>>> list(keys)
['eggs', 'sausage', 'bacon', 'spam']
>>> list(values)
[2, 1, 1, 500]

>>> # view objects are dynamic and reflect dict changes
>>> del dishes['eggs']
>>> del dishes['sausage']
>>> list(keys)
['bacon', 'spam']

>>> # set operations
>>> keys & {'eggs', 'bacon', 'salad'}
{'bacon'}
>>> keys ^ {'sausage', 'juice'} == {'juice', 'sausage', 'bacon', 'spam'}
True
>>> keys | ['juice', 'juice', 'juice'] == {'bacon', 'spam', 'juice'}
True

>>> # get back a read-only proxy for the original dictionary
>>> values.mapping
mappingproxy({'bacon': 1, 'spam': 500})
>>> values.mapping['spam']
500

Context Manager 型別

Python 的 with 語句支援由 context manager 定義的執行時上下文的概念。這是透過一對方法實現的,這些方法允許使用者定義的類定義一個在語句體執行之前進入、在語句結束時退出的執行時上下文

contextmanager.__enter__()

進入執行時上下文,並返回該物件或與執行時上下文相關的另一個物件。此方法返回的值繫結到使用此 context manager 的 with 語句的 as 子句中的識別符號。

返回自身的 context manager 的一個例子是檔案物件。檔案物件從 __enter__() 返回自身,以便 open() 可以在 with 語句中使用作為上下文表達式。

返回相關物件的 context manager 的一個例子是由 decimal.localcontext() 返回的。這些管理器將活動的 decimal 上下文設定為原始 decimal 上下文的副本,然後返回該副本。這允許在 with 語句的正文中對當前 decimal 上下文進行更改,而不會影響 with 語句外的程式碼。

contextmanager.__exit__(exc_type, exc_val, exc_tb)

退出執行時上下文,並返回一個布林標誌,指示是否應抑制發生的任何異常。如果在執行 with 語句的主體時發生異常,則引數包含異常型別、值和回溯資訊。否則,所有三個引數都為 None

從此方法返回真值將導致 with 語句抑制異常,並繼續執行 with 語句之後的下一條語句。否則,在方法完成執行後,異常將繼續傳播。在此方法執行期間發生的異常將替換在 with 語句主體中發生的任何異常。

引發的異常不應被顯式重新引發——相反,該方法應返回一個假值,以指示該方法已成功完成並且不希望抑制已引發的異常。這允許上下文管理程式碼輕鬆檢測 __exit__() 方法是否實際上失敗。

Python 定義了幾個 context manager 來支援輕鬆的執行緒同步、檔案的及時關閉或其他物件,以及更簡單的活動 decimal 算術上下文操作。具體型別除實現 context management protocol 外,不作特殊處理。有關一些示例,請參閱 contextlib 模組。

Python 的生成器contextlib.contextmanager 裝飾器提供了一種方便的方式來實現這些協議。如果一個生成器函式被 contextlib.contextmanager 裝飾器裝飾,它將返回一個實現必要的 __enter__()__exit__() 方法的 context manager,而不是未裝飾的生成器函式產生的迭代器。

請注意,Python/C API 中的 Python 物件型別結構沒有為這些方法設定特定的槽。希望定義這些方法的擴充套件型別必須將它們提供為普通的可 Python 訪問方法。與設定執行時上下文的開銷相比,查詢單個類字典的開銷可以忽略不計。

Type Annotation 型別 — Generic Alias, Union

型別註解的核心內建型別是 Generic AliasUnion

Generic Alias 型別

GenericAlias 物件通常透過下標一個類來建立。它們最常用於容器類,如 listdict。例如,list[int] 是透過用引數 int 下標 list 類建立的 GenericAlias 物件。GenericAlias 物件主要用於型別註解

備註

通常只能下標實現特殊方法 __class_getitem__() 的類。

GenericAlias 物件充當泛型型別的代理,實現*引數化泛型*。

對於容器類,提供給類下標的引數可以指示物件所包含元素的型別。例如,set[bytes] 可用於型別註解,以表示一個所有元素都為 bytes 型別的 set

對於定義了 __class_getitem__() 但不是容器的類,提供給類下標的引數通常會指示物件上定義的某個或多個方法的返回型別。例如,正則表示式可用於 str 資料型別和 bytes 資料型別。

  • 如果 x = re.search('foo', 'foo'),則 x 將是一個 re.Match 物件,其中 x.group(0)x[0] 的返回值都將是 str 型別。我們可以使用 GenericAlias re.Match[str] 在型別註解中表示這種型別的物件。

  • 如果 y = re.search(b'bar', b'bar')(注意 bytesb),則 y 也將是 re.Match 的例項,但 y.group(0)y[0] 的返回值都將是 bytes 型別。在型別註解中,我們將用 re.Match[bytes] 表示這種 re.Match 物件。

GenericAlias 物件是 types.GenericAlias 類的例項,它也可以用來直接建立 GenericAlias 物件。

T[X, Y, ...]

建立一個 GenericAlias,表示由型別 XY 等引數化的型別 T(具體取決於所使用的 T)。例如,一個期望包含 float 元素的 list 的函式

def average(values: list[float]) -> float:
    return sum(values) / len(values)

另一個使用對映物件的示例,使用 dict,它是一種通用型別,需要兩個型別引數來表示鍵型別和值型別。在此示例中,該函式需要一個鍵型別為 str、值為 intdict

def send_post_request(url: str, body: dict[str, int]) -> None:
    ...

內建函式 isinstance()issubclass() 不接受 GenericAlias 型別作為第二個引數。

>>> isinstance([1, 2], list[str])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: isinstance() argument 2 cannot be a parameterized generic

Python 執行時不會強制執行 型別註解。這同樣適用於泛型型別及其型別引數。當從 GenericAlias 建立容器物件時,容器中的元素不會根據其型別進行檢查。例如,以下程式碼不推薦使用,但可以執行而不會出錯:

>>> t = list[str]
>>> t([1, 2, 3])
[1, 2, 3]

此外,引數化泛型在物件建立過程中會擦除型別引數。

>>> t = list[str]
>>> type(t)
<class 'types.GenericAlias'>

>>> l = t()
>>> type(l)
<class 'list'>

對泛型呼叫 repr()str() 會顯示引數化型別。

>>> repr(list[int])
'list[int]'

>>> str(list[int])
'list[int]'

泛型容器的 __getitem__() 方法會引發異常,以防止 dict[str][str] 等錯誤。

>>> dict[str][str]
Traceback (most recent call last):
  ...
TypeError: dict[str] is not a generic class

然而,當使用 型別變數 時,此類表示式是有效的。索引必須包含與 GenericAlias 物件 __args__ 中的型別變數項一樣多的元素。

>>> from typing import TypeVar
>>> Y = TypeVar('Y')
>>> dict[str, Y][int]
dict[str, int]

標準泛型類

以下標準庫類支援引數化泛型。此列表不詳盡。

GenericAlias 物件的特殊屬性

所有引數化泛型都實現了特殊的只讀屬性。

genericalias.__origin__

此屬性指向非引數化的泛型類。

>>> list[int].__origin__
<class 'list'>
genericalias.__args__

此屬性是一個 tuple(可能長度為 1),包含傳遞給泛型類的原始 __class_getitem__() 的泛型型別。

>>> dict[str, list[int]].__args__
(<class 'str'>, list[int])
genericalias.__parameters__

此屬性是一個惰性計算的元組(可能為空),包含在 __args__ 中找到的唯一型別變數。

>>> from typing import TypeVar

>>> T = TypeVar('T')
>>> list[T].__parameters__
(~T,)

備註

具有 typing.ParamSpec 引數的 GenericAlias 物件可能沒有正確的 __parameters__,因為 typing.ParamSpec 主要用於靜態型別檢查。

genericalias.__unpacked__

一個布林值,如果別名已透過 * 運算子解包(參見 TypeVarTuple),則為 True。

在 3.11 版本中新增。

參見

PEP 484 - 型別提示

介紹 Python 的型別註解框架。

PEP 585 - 標準集合中的型別提示泛型

介紹原生引數化標準庫類(前提是它們實現了特殊的類方法 __class_getitem__())的能力。

泛型使用者自定義泛型typing.Generic

關於如何實現可在執行時引數化並被靜態型別檢查器理解的泛型類的文件。

在 3.9 版本中新增。

聯合型別

聯合物件儲存了多個 型別物件|(按位或)運算的值。這些型別主要用於 型別註解。聯合型別表示式比下標引用 typing.Union 提供了更簡潔的型別提示語法。

X | Y | ...

定義一個聯合物件,它包含型別 XY 等。 X | Y 表示 X 或 Y。它等同於 typing.Union[X, Y]。例如,以下函式需要一個型別為 intfloat 的引數。

def square(number: int | float) -> int | float:
    return number ** 2

備註

執行時不能使用 | 運算子來定義一個或多個成員是前向引用的聯合。例如,int | "Foo"(其中 "Foo" 是對尚未定義的類的引用)在執行時會失敗。對於包含前向引用的聯合,請將整個表示式作為字串提供,例如 "int | Foo"

union_object == other

聯合物件可以與其他聯合物件進行相等性測試。詳細資訊

  • 聯合的聯合會被展平。

    (int | str) | float == int | str | float
    
  • 冗餘型別會被移除。

    int | str | int == int | str
    
  • 比較聯合時,順序會被忽略。

    int | str == str | int
    
  • 它建立 typing.Union 的例項。

    int | str == typing.Union[int, str]
    type(int | str) is typing.Union
    
  • 可選型別可以拼寫為與 None 的聯合。

    str | None == typing.Optional[str]
    
isinstance(obj, union_object)
issubclass(obj, union_object)

對聯合物件的 isinstance()issubclass() 呼叫也受支援。

>>> isinstance("", int | str)
True

然而,聯合物件中的 引數化泛型 無法被檢查。

>>> isinstance(1, int | list[int])  # short-circuit evaluation
True
>>> isinstance([1], int | list[int])
Traceback (most recent call last):
  ...
TypeError: isinstance() argument 2 cannot be a parameterized generic

聯合物件的使用者可見型別可以從 typing.Union 訪問,並用於 isinstance() 檢查。

>>> import typing
>>> isinstance(int | str, typing.Union)
True
>>> typing.Union()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot create 'typing.Union' instances

備註

型別物件的 __or__() 方法是為了支援 X | Y 語法而新增的。如果元類實現了 __or__(),則 Union 可能會覆蓋它。

>>> class M(type):
...     def __or__(self, other):
...         return "Hello"
...
>>> class C(metaclass=M):
...     pass
...
>>> C | int
'Hello'
>>> int | C
int | C

參見

PEP 604 - 提出 X | Y 語法和 Union 型別的 PEP。

在 3.10 版本加入。

版本 3.14 中已更改: Union 物件現在是 typing.Union 的例項。以前,它們是 types.UnionType 的例項,後者仍然是 typing.Union 的別名。

其他內建型別

直譯器支援多種其他型別的物件。其中大多數只支援一到兩個操作。

模組

模組的唯一特殊操作是屬性訪問:m.name,其中 m 是一個模組,name 訪問 m 的符號表中定義的名稱。可以為模組屬性賦值。(請注意,import 語句嚴格來說不是對模組物件的操作;import foo 不需要名為 foo 的模組物件存在,而是需要一個在某處定義的(外部)名為 foo 的模組的定義。)

每個模組的一個特殊屬性是 __dict__。這是包含模組符號表的字典。修改此字典實際上會更改模組的符號表,但無法直接為 __dict__ 屬性賦值(您可以編寫 m.__dict__['a'] = 1,這將定義 m.a1,但不能編寫 m.__dict__ = {})。直接修改 __dict__ 不推薦。

內置於直譯器的模組如下所示:<module 'sys' (built-in)>。如果從檔案載入,則顯示為 <module 'os' from '/usr/local/lib/pythonX.Y/os.pyc'>

類和類例項

有關這些內容,請參閱 物件、值和型別類定義

函式

函式物件透過函式定義建立。函式物件的唯一操作是呼叫它:func(argument-list)

實際上有兩種函式物件:內建函式和使用者定義函式。兩者都支援相同的操作(呼叫函式),但實現不同,因此物件型別也不同。

有關更多資訊,請參閱 函式定義

方法

方法是使用屬性表示法呼叫的函式。有兩種:內建方法(例如列表上的 append())和類例項方法。內建方法與支援它們的物件型別一起描述。

如果透過例項訪問方法(在類名稱空間中定義的函式),則會得到一個特殊物件:繫結方法(也稱為 例項方法)物件。呼叫時,它會將 self 引數新增到引數列表中。繫結方法有兩個特殊的只讀屬性:m.__self__ 是方法操作的物件,而 m.__func__ 是實現該方法的函式。呼叫 m(arg-1, arg-2, ..., arg-n) 完全等同於呼叫 m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)

函式物件 一樣,繫結方法物件支援獲取任意屬性。但是,由於方法屬性實際上儲存在底層函式物件(method.__func__)上,因此不允許在繫結方法上設定方法屬性。嘗試在方法上設定屬性會導致引發 AttributeError。要設定方法屬性,您需要顯式地在底層函式物件上設定它。

>>> class C:
...     def method(self):
...         pass
...
>>> c = C()
>>> c.method.whoami = 'my name is method'  # can't set on the method
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'method' object has no attribute 'whoami'
>>> c.method.__func__.whoami = 'my name is method'
>>> c.method.whoami
'my name is method'

有關更多資訊,請參閱 例項方法

程式碼物件

程式碼物件由實現用來表示“偽編譯”的可執行 Python 程式碼,例如函式體。它們與函式物件不同,因為它們不包含對其全域性執行環境的引用。程式碼物件由內建的 compile() 函式返回,並且可以透過函式物件的 __code__ 屬性提取。另請參閱 code 模組。

訪問 __code__ 會引發一個帶有引數 obj"__code__"稽核事件 object.__getattr__

可以透過將程式碼物件(而不是源字串)傳遞給 exec()eval() 內建函式來執行或評估它。

有關更多資訊,請參閱 標準型別層次結構

型別物件

型別物件表示各種物件型別。物件的型別透過內建函式 type() 訪問。型別沒有特殊的運算子。標準模組 types 定義了所有標準內建型別的名稱。

型別顯示如下:<class 'int'>

Null 物件

此物件由不顯式返回值的方法返回。它不支援任何特殊操作。只有一個 Null 物件,名為 None(內建名稱)。type(None)() 會產生相同的單例。

它被寫為 None

Ellipsis 物件

此物件通常用於指示某項被省略。它不支援任何特殊操作。只有一個 Ellipsis 物件,名為 Ellipsis(內建名稱)。type(Ellipsis)() 會產生 Ellipsis 單例。

它被寫為 Ellipsis...

在典型用法中,... 作為 Ellipsis 物件出現在幾個不同的地方,例如:

Python 還在並非 Ellipsis 物件的地方使用三個點,例如:

  • Doctest 的 ELLIPSIS,作為缺失內容的模式。

  • 當輸入不完整時,互動式 Shell 的預設 Python 提示符。

最後,Python 文件經常使用三個點來表示省略的內容,即使在也使用它們作為 Ellipsis 的程式碼示例中也是如此。

NotImplemented 物件

當比較和二進位制運算無法處理不支援的型別時,將返回此物件。有關更多資訊,請參閱 比較。存在一個 NotImplemented 物件。 type(NotImplemented)() 會產生單例例項。

它被寫為 NotImplemented

內部物件

有關這些資訊,請參閱 標準型別層次結構。它描述了 棧幀物件回溯物件 和切片物件。

特殊屬性

實現為幾個物件型別添加了一些特殊的只讀屬性(在相關時)。其中一些未在內建函式 dir() 中報告。

definition.__name__

類、函式、方法、描述符或生成器例項的名稱。

definition.__qualname__

類、函式、方法、描述符或生成器例項的 限定名

在 3.3 版本加入。

definition.__module__

定義類或函式的模組的名稱。

definition.__doc__

類或函式的文件字串,如果未定義則為 None

definition.__type_params__

泛型類、函式和 類型別名型別引數。對於非泛型的類和函式,這將是一個空元組。

3.12 新版功能.

整數字符串轉換長度限制

CPython 有一個全侷限制,用於在 intstr 之間進行轉換,以減輕拒絕服務攻擊。此限制*僅*適用於十進位制或其他非 2 的冪數制。十六進位制、八進位制和二進位制轉換不受限制。該限制是可配置的。

CPython 中的 int 型別是儲存在二進位制形式中的任意長度數字(通常稱為“bignum”)。不存在可以線性時間將字串轉換為二進位制整數或將二進位制整數轉換為字串的演算法,*除非*基數是 2 的冪。即使是最佳已知的十進位制演算法也具有亞二次複雜度。轉換一個大值,例如 int('1' * 500_000),在快速 CPU 上可能需要一秒多。

限制轉換大小提供了一種實用的方法來避免 CVE 2020-10735

當非線性轉換演算法涉及時,限制應用於輸入或輸出字串中的數字字元數量。下劃線和符號不計入此限制。

當操作會超出限制時,會引發 ValueError

>>> import sys
>>> sys.set_int_max_str_digits(4300)  # Illustrative, this is the default.
>>> _ = int('2' * 5432)
Traceback (most recent call last):
...
ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 5432 digits; use sys.set_int_max_str_digits() to increase the limit
>>> i = int('2' * 4300)
>>> len(str(i))
4300
>>> i_squared = i*i
>>> len(str(i_squared))
Traceback (most recent call last):
...
ValueError: Exceeds the limit (4300 digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit
>>> len(hex(i_squared))
7144
>>> assert int(hex(i_squared), base=16) == i*i  # Hexadecimal is unlimited.

預設限制為 4300 位數字,如 sys.int_info.default_max_str_digits 中所示。可配置的最低限制為 640 位數字,如 sys.int_info.str_digits_check_threshold 中所示。

驗證

>>> import sys
>>> assert sys.int_info.default_max_str_digits == 4300, sys.int_info
>>> assert sys.int_info.str_digits_check_threshold == 640, sys.int_info
>>> msg = int('578966293710682886880994035146873798396722250538762761564'
...           '9252925514383915483333812743580549779436104706260696366600'
...           '571186405732').to_bytes(53, 'big')
...

在 3.11 版本中新增。

受影響的 API

該限制僅適用於 intstrbytes 之間可能耗時的轉換。

  • int(string),預設基數為 10。

  • int(string, base),對於所有不是 2 的冪的基數。

  • str(integer).

  • repr(integer).

  • 任何其他轉換為十進位制的字串,例如 f"{integer}""{}".format(integer)b"%d" % integer

這些限制不適用於具有線性演算法的函式。

配置限制

在 Python 啟動之前,您可以使用環境變數或直譯器命令列標誌來配置限制。

從程式碼中,您可以使用這些 sys API 來檢查當前限制並設定新的限制。

有關預設值和最小值的資訊可以在 sys.int_info 中找到。

在 3.11 版本中新增。

注意

設定低限制*可能*會導致問題。雖然罕見,但存在一些程式碼在其源中使用十進位制整數常量,這些常量超過了最小閾值。設定限制的一個後果是,包含長於限制的十進位制整數文字的 Python 原始碼將在解析過程中遇到錯誤,通常是在啟動或匯入時,甚至在安裝時 - 任何時候不存在現有 .pyc 檔案都會出現此問題。包含此類大型常量的原始碼的解決方法是將其轉換為 0x 十六進位制形式,因為它沒有限制。

如果您使用低限制,請徹底測試您的應用程式。確保您的測試在透過環境變數或標誌早期設定的限制下執行,以便它在啟動時甚至在可能呼叫 Python 來預編譯 .py 原始檔到 .pyc 檔案的任何安裝步驟中都適用。