內置類(lèi)型?
以下部分描述了解釋器中內置的標準類(lèi)型。
主要內置類(lèi)型有數字、序列、映射、類(lèi)、實(shí)例和異常。
有些多項集類(lèi)是可變的。 它們用于添加、移除或重排其成員的方法將原地執行,并不返回特定的項,絕對不會(huì )返回多項集實(shí)例自身而是返回 None
。
有些操作受多種對象類(lèi)型的支持;特別地,實(shí)際上所有對象都可以比較是否相等、檢測邏輯值,以及轉換為字符串(使用 repr()
函數或略有差異的 str()
函數)。 后一個(gè)函數是在對象由 print()
函數輸出時(shí)被隱式地調用的。
邏輯值檢測?
任何對象都可以進(jìn)行邏輯值的檢測,以便在 if
或 while
作為條件或是作為下文所述布爾運算的操作數來(lái)使用。
一個(gè)對象在默認情況下均被視為真值,除非當該對象被調用時(shí)其所屬類(lèi)定義了 __bool__()
方法且返回 False
或是定義了 __len__()
方法且返回零。 1 下面基本完整地列出了會(huì )被視為假值的內置對象:
被定義為假值的常量:
None
和False
。任何數值類(lèi)型的零:
0
,0.0
,0j
,Decimal(0)
,Fraction(0, 1)
空的序列和多項集:
''
,()
,[]
,{}
,set()
,range(0)
產(chǎn)生布爾值結果的運算和內置函數總是返回 0
或 False
作為假值,1
或 True
作為真值,除非另行說(shuō)明。 (重要例外:布爾運算 or
和 and
總是返回其中一個(gè)操作數。)
布爾運算 --- and
, or
, not
?
這些屬于布爾運算,按優(yōu)先級升序排列:
運算 |
結果: |
備注 |
---|---|---|
|
if x is false, then y, else x |
(1) |
|
if x is false, then x, else y |
(2) |
|
if x is false, then |
(3) |
注釋?zhuān)?/p>
這是個(gè)短路運算符,因此只有在第一個(gè)參數為假值時(shí)才會(huì )對第二個(gè)參數求值。
這是個(gè)短路運算符,因此只有在第一個(gè)參數為真值時(shí)才會(huì )對第二個(gè)參數求值。
not
的優(yōu)先級比非布爾運算符低,因此not a == b
會(huì )被解讀為not (a == b)
而a == not b
會(huì )引發(fā)語(yǔ)法錯誤。
比較運算?
在 Python 中有八種比較運算符。 它們的優(yōu)先級相同(比布爾運算的優(yōu)先級高)。 比較運算可以任意串連;例如,x < y <= z
等價(jià)于 x < y and y <= z
,前者的不同之處在于 y 只被求值一次(但在兩種情況下當 x < y
結果為假值時(shí) z 都不會(huì )被求值)。
此表格匯總了比較運算:
運算 |
含意 |
---|---|
|
嚴格小于 |
|
小于或等于 |
|
嚴格大于 |
|
大于或等于 |
|
等于 |
|
不等于 |
|
對象標識 |
|
否定的對象標識 |
除不同的數字類(lèi)型外,不同類(lèi)型的對象不能進(jìn)行相等比較。==
運算符總有定義,但對于某些對象類(lèi)型(例如,類(lèi)對象),它等于 is
。其他 <
、<=
、>
和 >=
運算符僅在有意義的地方定義。例如,當參與比較的參數之一為復數時(shí),它們會(huì )拋出 TypeError
異常。
Non-identical instances of a class normally compare as non-equal unless the
class defines the __eq__()
method.
Instances of a class cannot be ordered with respect to other instances of the
same class, or other types of object, unless the class defines enough of the
methods __lt__()
, __le__()
, __gt__()
, and
__ge__()
(in general, __lt__()
and
__eq__()
are sufficient, if you want the conventional meanings of the
comparison operators).
is
和 is not
運算符無(wú)法自定義;并且它們可以被應用于任意兩個(gè)對象而不會(huì )引發(fā)異常。
還有兩種具有相同語(yǔ)法優(yōu)先級的運算 in
和 not in
,它們被 iterable 或實(shí)現了 __contains__()
方法的類(lèi)型所支持。
數字類(lèi)型 --- int
, float
, complex
?
存在三種不同的數字類(lèi)型: 整數, 浮點(diǎn)數 和 復數。 此外,布爾值屬于整數的子類(lèi)型。 整數具有無(wú)限的精度。 浮點(diǎn)數通常使用 C 中的 double 來(lái)實(shí)現;有關(guān)你的程序運行所在機器上浮點(diǎn)數的精度和內部表示法可在 sys.float_info
中查看。 復數包含實(shí)部和虛部,分別以一個(gè)浮點(diǎn)數表示。 要從一個(gè)復數 z 中提取這兩個(gè)部分,可使用 z.real
和 z.imag
。 (標準庫包含附加的數字類(lèi)型,如表示有理數的 fractions.Fraction
以及以用戶(hù)定制精度表示浮點(diǎn)數的 decimal.Decimal
。)
數字是由數字字面值或內置函數與運算符的結果來(lái)創(chuàng )建的。 不帶修飾的整數字面值(包括十六進(jìn)制、八進(jìn)制和二進(jìn)制數)會(huì )生成整數。 包含小數點(diǎn)或冪運算符的數字字面值會(huì )生成浮點(diǎn)數。 在數字字面值末尾加上 'j'
或 'J'
會(huì )生成虛數(實(shí)部為零的復數),你可以將其與整數或浮點(diǎn)數相加來(lái)得到具有實(shí)部和虛部的復數。
Python 完全支持混合運算:當一個(gè)二元算術(shù)運算符的操作數有不同數值類(lèi)型時(shí),"較窄"類(lèi)型的操作數會(huì )拓寬到另一個(gè)操作數的類(lèi)型,其中整數比浮點(diǎn)數窄,浮點(diǎn)數比復數窄。不同類(lèi)型的數字之間的比較,同比較這些數字的精確值一樣。2
構造函數 int()
、 float()
和 complex()
可以用來(lái)構造特定類(lèi)型的數字。
所有數字類(lèi)型(復數除外)都支持下列運算(有關(guān)運算優(yōu)先級,請參閱:運算符優(yōu)先級):
運算 |
結果: |
備注 |
完整文檔 |
---|---|---|---|
|
x 和 y 的和 |
||
|
x 和 y 的差 |
||
|
x 和 y 的乘積 |
||
|
x 和 y 的商 |
||
|
x 和 y 的商數 |
(1) |
|
|
|
(2) |
|
|
x 取反 |
||
|
x 不變 |
||
|
x 的絕對值或大小 |
||
|
將 x 轉換為整數 |
(3)(6) |
|
|
將 x 轉換為浮點(diǎn)數 |
(4)(6) |
|
|
一個(gè)帶有實(shí)部 re 和虛部 im 的復數。im 默認為0。 |
(6) |
|
|
復數 c 的共軛 |
||
|
|
(2) |
|
|
x 的 y 次冪 |
(5) |
|
|
x 的 y 次冪 |
(5) |
注釋?zhuān)?/p>
也稱(chēng)為整數除法。 結果值是一個(gè)整數,但結果的類(lèi)型不一定是 int。 運算結果總是向負無(wú)窮的方向舍入:
1//2
為0
,(-1)//2
為-1
,1//(-2)
為-1
而(-1)//(-2)
為0
。不可用于復數。 而應在適當條件下使用
abs()
轉換為浮點(diǎn)數。從浮點(diǎn)數轉換為整數會(huì )被舍入或是像在 C 語(yǔ)言中一樣被截斷;請參閱
math.floor()
和math.ceil()
函數查看轉換的完整定義。float 也接受字符串 "nan" 和附帶可選前綴 "+" 或 "-" 的 "inf" 分別表示非數字 (NaN) 以及正或負無(wú)窮。
Python 將
pow(0, 0)
和0 ** 0
定義為1
,這是編程語(yǔ)言的普遍做法。接受的數字字面值包括數碼
0
到9
或任何等效的 Unicode 字符(具有Nd
特征屬性的代碼點(diǎn))。See https://www.unicode.org/Public/14.0.0/ucd/extracted/DerivedNumericType.txt for a complete list of code points with the
Nd
property.
所有 numbers.Real
類(lèi)型 (int
和 float
) 還包括下列運算:
運算 |
結果: |
---|---|
x 截斷為 |
|
x 舍入到 n 位小數,半數值會(huì )舍入到偶數。 如果省略 n,則默認為 0。 |
|
<= x 的最大 |
|
>= x 的最小 |
有關(guān)更多的數字運算請參閱 math
和 cmath
模塊。
整數類(lèi)型的按位運算?
按位運算只對整數有意義。 計算按位運算的結果,就相當于使用無(wú)窮多個(gè)二進(jìn)制符號位對二的補碼執行操作。
二進(jìn)制按位運算的優(yōu)先級全都低于數字運算,但又高于比較運算;一元運算 ~
具有與其他一元算術(shù)運算 (+
and -
) 相同的優(yōu)先級。
此表格是以?xún)?yōu)先級升序排序的按位運算列表:
運算 |
結果: |
備注 |
---|---|---|
|
x 和 y 按位 或 |
(4) |
|
x 和 y 按位 異或 |
(4) |
|
x 和 y 按位 與 |
(4) |
|
x 左移 n 位 |
(1)(2) |
|
x 右移 n 位 |
(1)(3) |
|
x 逐位取反 |
注釋?zhuān)?/p>
負的移位數是非法的,會(huì )導致引發(fā)
ValueError
。左移 n 位等價(jià)于乘以
pow(2, n)
。右移 n 位等價(jià)于除以
pow(2, n)
,作向下取整除法。使用帶有至少一個(gè)額外符號擴展位的有限個(gè)二進(jìn)制補碼表示(有效位寬度為
1 + max(x.bit_length(), y.bit_length())
或以上)執行這些計算就足以獲得相當于有無(wú)數個(gè)符號位時(shí)的同樣結果。
整數類(lèi)型的附加方法?
int 類(lèi)型實(shí)現了 numbers.Integral
abstract base class。 此外,它還提供了其他幾個(gè)方法:
- int.bit_length()?
返回以二進(jìn)制表示一個(gè)整數所需要的位數,不包括符號位和前面的零:
>>> n = -37 >>> bin(n) '-0b100101' >>> n.bit_length() 6
更準確地說(shuō),如果
x
非零,則x.bit_length()
是使得2**(k-1) <= abs(x) < 2**k
的唯一正整數k
。 同樣地,當abs(x)
小到足以具有正確的舍入對數時(shí),則k = 1 + int(log(abs(x), 2))
。 如果x
為零,則x.bit_length()
返回0
。等價(jià)于:
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()?
返回整數的絕對值的二進(jìn)制表示中 1 的個(gè)數。也被稱(chēng)為 population count。示例:
>>> n = 19 >>> bin(n) '0b10011' >>> n.bit_count() 3 >>> (-n).bit_count() 3
等價(jià)于:
def bit_count(self): return bin(self).count("1")
3.10 新版功能.
- int.to_bytes(length=1, byteorder='big', *, signed=False)?
返回表示一個(gè)整數的字節數組。
>>> (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'
The integer is represented using length bytes, and defaults to 1. An
OverflowError
is raised if the integer is not representable with the given number of bytes.The byteorder argument determines the byte order used to represent the integer, and defaults to
"big"
. If byteorder is"big"
, the most significant byte is at the beginning of the byte array. If byteorder is"little"
, the most significant byte is at the end of the byte array.signed 參數確定是否使用二的補碼來(lái)表示整數。 如果 signed 為
False
并且給出的是負整數,則會(huì )引發(fā)OverflowError
。 signed 的默認值為False
。The default values can be used to conveniently turn an integer into a single byte object. However, when using the default arguments, don't try to convert a value greater than 255 or you'll get an
OverflowError
:>>> (65).to_bytes() b'A'
等價(jià)于:
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 版更改: Added default argument values for
length
andbyteorder
.
- 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 參數必須為一個(gè) bytes-like object 或是生成字節的可迭代對象。
The byteorder argument determines the byte order used to represent the integer, and defaults to
"big"
. If byteorder is"big"
, the most significant byte is at the beginning of the byte array. If byteorder is"little"
, the most significant byte is at the end of the byte array. To request the native byte order of the host system, usesys.byteorder
as the byte order value.signed 參數指明是否使用二的補碼來(lái)表示整數。
等價(jià)于:
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 版更改: Added default argument value for
byteorder
.
- int.as_integer_ratio()?
返回一對整數,其比率正好等于原整數并且分母為正數。 整數的比率總是用這個(gè)整數本身作為分子,
1
作為分母。3.8 新版功能.
浮點(diǎn)類(lèi)型的附加方法?
float 類(lèi)型實(shí)現了 numbers.Real
abstract base class。 float 還具有以下附加方法。
- float.as_integer_ratio()?
返回一對整數,其比率正好等于原浮點(diǎn)數并且分母為正數。 無(wú)窮大會(huì )引發(fā)
OverflowError
而 NaN 則會(huì )引發(fā)ValueError
。
- float.is_integer()?
如果 float 實(shí)例可用有限位整數表示則返回
True
,否則返回False
:>>> (-2.0).is_integer() True >>> (3.2).is_integer() False
兩個(gè)方法均支持與十六進(jìn)制數字符串之間的轉換。 由于 Python 浮點(diǎn)數在內部存儲為二進(jìn)制數,因此浮點(diǎn)數與 十進(jìn)制數 字符串之間的轉換往往會(huì )導致微小的舍入錯誤。 而十六進(jìn)制數字符串卻允許精確地表示和描述浮點(diǎn)數。 這在進(jìn)行調試和數值工作時(shí)非常有用。
- float.hex()?
以十六進(jìn)制字符串的形式返回一個(gè)浮點(diǎn)數表示。 對于有限浮點(diǎn)數,這種表示法將總是包含前導的
0x
和尾隨的p
加指數。
- classmethod float.fromhex(s)?
返回以十六進(jìn)制字符串 s 表示的浮點(diǎn)數的類(lèi)方法。 字符串 s 可以帶有前導和尾隨的空格。
請注意 float.hex()
是實(shí)例方法,而 float.fromhex()
是類(lèi)方法。
十六進(jìn)制字符串采用的形式為:
[sign] ['0x'] integer ['.' fraction] ['p' exponent]
可選的 sign
可以是 +
或 -
,integer
和 fraction
是十六進(jìn)制數碼組成的字符串,exponent
是帶有可選前導符的十進(jìn)制整數。 大小寫(xiě)沒(méi)有影響,在 integer 或 fraction 中必須至少有一個(gè)十六進(jìn)制數碼。 此語(yǔ)法類(lèi)似于 C99 標準的 6.4.4.2 小節中所描述的語(yǔ)法,也是 Java 1.5 以上所使用的語(yǔ)法。 特別地,float.hex()
的輸出可以用作 C 或 Java 代碼中的十六進(jìn)制浮點(diǎn)數字面值,而由 C 的 %a
格式字符或 Java 的 Double.toHexString
所生成的十六進(jìn)制數字符串由為 float.fromhex()
所接受。
請注意 exponent 是十進(jìn)制數而非十六進(jìn)制數,它給出要與系數相乘的 2 的冪次。 例如,十六進(jìn)制數字符串 0x3.a7p10
表示浮點(diǎn)數 (3 + 10./16 + 7./16**2) * 2.0**10
即 3740.0
:
>>> float.fromhex('0x3.a7p10')
3740.0
對 3740.0
應用反向轉換會(huì )得到另一個(gè)代表相同數值的十六進(jìn)制數字符串:
>>> float.hex(3740.0)
'0x1.d380000000000p+11'
數字類(lèi)型的哈希運算?
For numbers x
and y
, possibly of different types, it's a requirement
that hash(x) == hash(y)
whenever x == y
(see the __hash__()
method documentation for more details). For ease of implementation and
efficiency across a variety of numeric types (including int
,
float
, decimal.Decimal
and fractions.Fraction
)
Python's hash for numeric types is based on a single mathematical function
that's defined for any rational number, and hence applies to all instances of
int
and fractions.Fraction
, and all finite instances of
float
and decimal.Decimal
. Essentially, this function is
given by reduction modulo P
for a fixed prime P
. The value of P
is
made available to Python as the modulus
attribute of
sys.hash_info
.
CPython implementation detail: 目前所用的質(zhì)數設定,在 C long 為 32 位的機器上 P = 2**31 - 1
而在 C long 為 64 位的機器上 P = 2**61 - 1
。
詳細規則如下所述:
如果
x = m / n
是一個(gè)非負的有理數且n
不可被P
整除,則定義hash(x)
為m * invmod(n, P) % P
,其中invmod(n, P)
是對n
模P
取反。如果
x = m / n
是一個(gè)非負的有理數且n
可被P
整除(但m
不能)則n
不能對P
降模,以上規則不適用;在此情況下則定義hash(x)
為常數值sys.hash_info.inf
。如果
x = m / n
是一個(gè)負的有理數則定義hash(x)
為-hash(-x)
。 如果結果哈希值為-1
則將其替換為-2
。特殊值
sys.hash_info.inf
和-sys.hash_info.inf
分別用于正無(wú)窮或負無(wú)窮的哈希值。對于一個(gè)
complex
值z
,會(huì )通過(guò)計算hash(z.real) + sys.hash_info.imag * hash(z.imag)
將實(shí)部和虛部的哈希值結合起來(lái),并進(jìn)行降模2**sys.hash_info.width
以使其處于range(-2**(sys.hash_info.width - 1), 2**(sys.hash_info.width - 1))
范圍之內。 同樣地,如果結果為-1
則將其替換為-2
。
為了闡明上述規則,這里有一些等價(jià)于內置哈希算法的 Python 代碼示例,可用于計算有理數、float
或 complex
的哈希值:
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
迭代器類(lèi)型?
Python 支持在容器中進(jìn)行迭代的概念。 這是通過(guò)使用兩個(gè)單獨方法來(lái)實(shí)現的;它們被用于允許用戶(hù)自定義類(lèi)對迭代的支持。 將在下文中詳細描述的序列總是支持迭代方法。
One method needs to be defined for container objects to provide iterable support:
- container.__iter__()?
Return an iterator object. The object is required to support the iterator protocol described below. If a container supports different types of iteration, additional methods can be provided to specifically request iterators for those iteration types. (An example of an object supporting multiple forms of iteration would be a tree structure which supports both breadth-first and depth-first traversal.) This method corresponds to the
tp_iter
slot of the type structure for Python objects in the Python/C API.
迭代器對象自身需要支持以下兩個(gè)方法,它們共同組成了 迭代器協(xié)議:
- iterator.__iter__()?
Return the iterator object itself. This is required to allow both containers and iterators to be used with the
for
andin
statements. This method corresponds to thetp_iter
slot of the type structure for Python objects in the Python/C API.
- iterator.__next__()?
Return the next item from the iterator. If there are no further items, raise the
StopIteration
exception. This method corresponds to thetp_iternext
slot of the type structure for Python objects in the Python/C API.
Python 定義了幾種迭代器對象以支持對一般和特定序列類(lèi)型、字典和其他更特別的形式進(jìn)行迭代。 除了迭代器協(xié)議的實(shí)現,特定類(lèi)型的其他性質(zhì)對迭代操作來(lái)說(shuō)都不重要。
一旦迭代器的 __next__()
方法引發(fā)了 StopIteration
,它必須一直對后續調用引發(fā)同樣的異常。 不遵循此行為特性的實(shí)現將無(wú)法正常使用。
生成器類(lèi)型?
Python 的 generator 提供了一種實(shí)現迭代器協(xié)議的便捷方式。 如果容器對象 __iter__()
方法被實(shí)現為一個(gè)生成器,它將自動(dòng)返回一個(gè)迭代器對象(從技術(shù)上說(shuō)是一個(gè)生成器對象),該對象提供 __iter__()
和 __next__()
方法。 有關(guān)生成器的更多信息可以參閱 yield 表達式的文檔。
序列類(lèi)型 --- list
, tuple
, range
?
有三種基本序列類(lèi)型:list, tuple 和 range 對象。 為處理 二進(jìn)制數據 和 文本字符串 而特別定制的附加序列類(lèi)型會(huì )在專(zhuān)門(mén)的小節中描述。
通用序列操作?
大多數序列類(lèi)型,包括可變類(lèi)型和不可變類(lèi)型都支持下表中的操作。 collections.abc.Sequence
ABC 被提供用來(lái)更容易地在自定義序列類(lèi)型上正確地實(shí)現這些操作。
此表按優(yōu)先級升序列出了序列操作。 在表格中,s 和 t 是具有相同類(lèi)型的序列,n, i, j 和 k 是整數而 x 是任何滿(mǎn)足 s 所規定的類(lèi)型和值限制的任意對象。
in
和 not in
操作具有與比較操作相同的優(yōu)先級。 +
(拼接) 和 *
(重復) 操作具有與對應數值運算相同的優(yōu)先級。 3
運算 |
結果: |
備注 |
---|---|---|
|
如果 s 中的某項等于 x 則結果為 |
(1) |
|
如果 s 中的某項等于 x 則結果為 |
(1) |
|
s 與 t 相拼接 |
(6)(7) |
|
相當于 s 與自身進(jìn)行 n 次拼接 |
(2)(7) |
|
s 的第 i 項,起始為 0 |
(3) |
|
s 從 i 到 j 的切片 |
(3)(4) |
|
s 從 i 到 j 步長(cháng)為 k 的切片 |
(3)(5) |
|
s 的長(cháng)度 |
|
|
s 的最小項 |
|
|
s 的最大項 |
|
|
x 在 s 中首次出現項的索引號(索引號在 i 或其后且在 j 之前) |
(8) |
|
x 在 s 中出現的總次數 |
相同類(lèi)型的序列也支持比較。 特別地,tuple 和 list 的比較是通過(guò)比較對應元素的字典順序。 這意味著(zhù)想要比較結果相等,則每個(gè)元素比較結果都必須相等,并且兩個(gè)序列長(cháng)度必須相同。 (完整細節請參閱語(yǔ)言參考的 比較運算 部分。)
Forward and reversed iterators over mutable sequences access values using an
index. That index will continue to march forward (or backward) even if the
underlying sequence is mutated. The iterator terminates only when an
IndexError
or a StopIteration
is encountered (or when the index
drops below zero).
注釋?zhuān)?/p>
雖然
in
和not in
操作在通常情況下僅被用于簡(jiǎn)單的成員檢測,某些專(zhuān)門(mén)化序列 (例如str
,bytes
和bytearray
) 也使用它們進(jìn)行子序列檢測:>>> "gg" in "eggs" True
小于
0
的 n 值會(huì )被當作0
來(lái)處理 (生成一個(gè)與 s 同類(lèi)型的空序列)。 請注意序列 s 中的項并不會(huì )被拷貝;它們會(huì )被多次引用。 這一點(diǎn)經(jīng)常會(huì )令 Python 編程新手感到困擾;例如:>>> lists = [[]] * 3 >>> lists [[], [], []] >>> lists[0].append(3) >>> lists [[3], [3], [3]]
具體的原因在于
[[]]
是一個(gè)包含了一個(gè)空列表的單元素列表,所以[[]] * 3
結果中的三個(gè)元素都是對這一個(gè)空列表的引用。 修改lists
中的任何一個(gè)元素實(shí)際上都是對這一個(gè)空列表的修改。 你可以用以下方式創(chuàng )建以不同列表為元素的列表:>>> lists = [[] for i in range(3)] >>> lists[0].append(3) >>> lists[1].append(5) >>> lists[2].append(7) >>> lists [[3], [5], [7]]
進(jìn)一步的解釋可以在 FAQ 條目 如何創(chuàng )建多維列表? 中查看。
如果 i 或 j 為負值,則索引順序是相對于序列 s 的末尾: 索引號會(huì )被替換為
len(s) + i
或len(s) + j
。 但要注意-0
仍然為0
。s 從 i 到 j 的切片被定義為所有滿(mǎn)足
i <= k < j
的索引號 k 的項組成的序列。 如果 i 或 j 大于len(s)
,則使用len(s)
。 如果 i 被省略或為None
,則使用0
。 如果 j 被省略或為None
,則使用len(s)
。 如果 i 大于等于 j,則切片為空。s 從 i 到 j 步長(cháng)為 k 的切片被定義為所有滿(mǎn)足
0 <= n < (j-i)/k
的索引號x = i + n*k
的項組成的序列。 換句話(huà)說(shuō),索引號為i
,i+k
,i+2*k
,i+3*k
,以此類(lèi)推,當達到 j 時(shí)停止 (但一定不包括 j)。 當 k 為正值時(shí),i 和 j 會(huì )被減至不大于len(s)
。 當 k 為負值時(shí),i 和 j 會(huì )被減至不大于len(s) - 1
。 如果 i 或 j 被省略或為None
,它們會(huì )成為“終止”值 (是哪一端的終止值則取決于 k 的符號)。 請注意,k 不可為零。 如果 k 為None
,則當作1
處理。拼接不可變序列總是會(huì )生成新的對象。 這意味著(zhù)通過(guò)重復拼接來(lái)構建序列的運行時(shí)開(kāi)銷(xiāo)將會(huì )基于序列總長(cháng)度的乘方。 想要獲得線(xiàn)性的運行時(shí)開(kāi)銷(xiāo),你必須改用下列替代方案之一:
如果拼接
str
對象,你可以構建一個(gè)列表并在最后使用str.join()
或是寫(xiě)入一個(gè)io.StringIO
實(shí)例并在結束時(shí)獲取它的值如果拼接
bytes
對象,你可以類(lèi)似地使用bytes.join()
或io.BytesIO
,或者你也可以使用bytearray
對象進(jìn)行原地拼接。bytearray
對象是可變的,并且具有高效的重分配機制對于其它類(lèi)型,請查看相應的文檔
某些序列類(lèi)型 (例如
range
) 僅支持遵循特定模式的項序列,因此并不支持序列拼接或重復。當 x 在 s 中找不到時(shí)
index
會(huì )引發(fā)ValueError
。 不是所有實(shí)現都支持傳入額外參數 i 和 j。 這兩個(gè)參數允許高效地搜索序列的子序列。 傳入這兩個(gè)額外參數大致相當于使用s[i:j].index(x)
,但是不會(huì )復制任何數據,并且返回的索引是相對于序列的開(kāi)頭而非切片的開(kāi)頭。
不可變序列類(lèi)型?
不可變序列類(lèi)型普遍實(shí)現而可變序列類(lèi)型未實(shí)現的唯一操作就是對 hash()
內置函數的支持。
這種支持允許不可變類(lèi)型,例如 tuple
實(shí)例被用作 dict
鍵,以及存儲在 set
和 frozenset
實(shí)例中。
嘗試對包含有不可哈希值的不可變序列進(jìn)行哈希運算將會(huì )導致 TypeError
。
可變序列類(lèi)型?
以下表格中的操作是在可變序列類(lèi)型上定義的。 collections.abc.MutableSequence
ABC 被提供用來(lái)更容易地在自定義序列類(lèi)型上正確實(shí)現這些操作。
表格中的 s 是可變序列類(lèi)型的實(shí)例,t 是任意可迭代對象,而 x 是符合對 s 所規定類(lèi)型與值限制的任何對象 (例如,bytearray
僅接受滿(mǎn)足 0 <= x <= 255
值限制的整數)。
運算 |
結果: |
備注 |
---|---|---|
|
將 s 的第 i 項替換為 x |
|
|
將 s 從 i 到 j 的切片替換為可迭代對象 t 的內容 |
|
|
等同于 |
|
|
將 |
(1) |
|
從列表中移除 |
|
|
將 x 添加到序列的末尾 (等同于 |
|
|
從 s 中移除所有項 (等同于 |
(5) |
|
創(chuàng )建 s 的淺拷貝 (等同于 |
(5) |
|
用 t 的內容擴展 s (基本上等同于 |
|
|
使用 s 的內容重復 n 次來(lái)對其進(jìn)行更新 |
(6) |
|
在由 i 給出的索引位置將 x 插入 s (等同于 |
|
|
提取在 i 位置上的項,并將其從 s 中移除 |
(2) |
|
刪除 s 中第一個(gè) |
(3) |
|
就地將列表中的元素逆序。 |
(4) |
注釋?zhuān)?/p>
t 必須與它所替換的切片具有相同的長(cháng)度。
可選參數 i 默認為
-1
,因此在默認情況下會(huì )移除并返回最后一項。當在 s 中找不到 x 時(shí)
remove()
操作會(huì )引發(fā)ValueError
。當反轉大尺寸序列時(shí)
reverse()
方法會(huì )原地修改該序列以保證空間經(jīng)濟性。 為提醒用戶(hù)此操作是通過(guò)間接影響進(jìn)行的,它并不會(huì )返回反轉后的序列。包括
clear()
和copy()
是為了與不支持切片操作的可變容器 (例如dict
和set
) 的接口保持一致。copy()
不是collections.abc.MutableSequence
ABC 的一部分,但大多數具體的可變序列類(lèi)都提供了它。3.3 新版功能:
clear()
和copy()
方法。n 值為一個(gè)整數,或是一個(gè)實(shí)現了
__index__()
的對象。 n 值為零或負數將清空序列。 序列中的項不會(huì )被拷貝;它們會(huì )被多次引用,正如 通用序列操作 中有關(guān)s * n
的說(shuō)明。
列表?
列表是可變序列,通常用于存放同類(lèi)項目的集合(其中精確的相似程度將根據應用而變化)。
- class list([iterable])?
可以用多種方式構建列表:
使用一對方括號來(lái)表示空列表:
[]
使用方括號,其中的項以逗號分隔:
[a]
,[a, b, c]
使用列表推導式:
[x for x in iterable]
使用類(lèi)型的構造器:
list()
或list(iterable)
構造器將構造一個(gè)列表,其中的項與 iterable 中的項具有相同的的值與順序。 iterable 可以是序列、支持迭代的容器或其它可迭代對象。 如果 iterable 已經(jīng)是一個(gè)列表,將創(chuàng )建并返回其副本,類(lèi)似于
iterable[:]
。 例如,list('abc')
返回['a', 'b', 'c']
而list( (1, 2, 3) )
返回[1, 2, 3]
。 如果沒(méi)有給出參數,構造器將創(chuàng )建一個(gè)空列表[]
。其它許多操作也會(huì )產(chǎn)生列表,包括
sorted()
內置函數。列表實(shí)現了所有 一般 和 可變 序列的操作。 列表還額外提供了以下方法:
- sort(*, key=None, reverse=False)?
此方法會(huì )對列表進(jìn)行原地排序,只使用
<
來(lái)進(jìn)行各項間比較。 異常不會(huì )被屏蔽 —— 如果有任何比較操作失敗,整個(gè)排序操作將失?。ǘ斜砜赡軙?huì )處于被部分修改的狀態(tài))。sort()
接受兩個(gè)僅限以關(guān)鍵字形式傳入的參數 (僅限關(guān)鍵字參數):key 指定帶有一個(gè)參數的函數,用于從每個(gè)列表元素中提取比較鍵 (例如
key=str.lower
)。 對應于列表中每一項的鍵會(huì )被計算一次,然后在整個(gè)排序過(guò)程中使用。 默認值None
表示直接對列表項排序而不計算一個(gè)單獨的鍵值。可以使用
functools.cmp_to_key()
將 2.x 風(fēng)格的 cmp 函數轉換為 key 函數。reverse 為一個(gè)布爾值。 如果設為
True
,則每個(gè)列表元素將按反向順序比較進(jìn)行排序。當順序大尺寸序列時(shí)此方法會(huì )原地修改該序列以保證空間經(jīng)濟性。 為提醒用戶(hù)此操作是通過(guò)間接影響進(jìn)行的,它并不會(huì )返回排序后的序列(請使用
sorted()
顯示地請求一個(gè)新的已排序列表實(shí)例)。sort()
方法確保是穩定的。 如果一個(gè)排序確保不會(huì )改變比較結果相等的元素的相對順序就稱(chēng)其為穩定的 --- 這有利于進(jìn)行多重排序(例如先按部門(mén)、再接薪級排序)。有關(guān)排序示例和簡(jiǎn)要排序教程,請參閱 排序指南 。
CPython implementation detail: 在一個(gè)列表被排序期間,嘗試改變甚至進(jìn)行檢測也會(huì )造成未定義的影響。 Python 的 C 實(shí)現會(huì )在排序期間將列表顯示為空,如果發(fā)現列表在排序期間被改變將會(huì )引發(fā)
ValueError
。
元組?
元組是不可變序列,通常用于儲存異構數據的多項集(例如由 enumerate()
內置函數所產(chǎn)生的二元組)。 元組也被用于需要同構數據的不可變序列的情況(例如允許存儲到 set
或 dict
的實(shí)例)。
- class tuple([iterable])?
可以用多種方式構建元組:
使用一對圓括號來(lái)表示空元組:
()
使用一個(gè)后綴的逗號來(lái)表示單元組:
a,
或(a,)
使用以逗號分隔的多個(gè)項:
a, b, c
or(a, b, c)
使用內置的
tuple()
:tuple()
或tuple(iterable)
構造器將構造一個(gè)元組,其中的項與 iterable 中的項具有相同的值與順序。 iterable 可以是序列、支持迭代的容器或其他可迭代對象。 如果 iterable 已經(jīng)是一個(gè)元組,會(huì )不加改變地將其返回。 例如,
tuple('abc')
返回('a', 'b', 'c')
而tuple( [1, 2, 3] )
返回(1, 2, 3)
。 如果沒(méi)有給出參數,構造器將創(chuàng )建一個(gè)空元組()
。請注意決定生成元組的其實(shí)是逗號而不是圓括號。 圓括號只是可選的,生成空元組或需要避免語(yǔ)法歧義的情況除外。 例如,
f(a, b, c)
是在調用函數時(shí)附帶三個(gè)參數,而f((a, b, c))
則是在調用函數時(shí)附帶一個(gè)三元組。元組實(shí)現了所有 一般 序列的操作。
對于通過(guò)名稱(chēng)訪(fǎng)問(wèn)相比通過(guò)索引訪(fǎng)問(wèn)更清晰的異構數據多項集,collections.namedtuple()
可能是比簡(jiǎn)單元組對象更為合適的選擇。
range 對象?
range
類(lèi)型表示不可變的數字序列,通常用于在 for
循環(huán)中循環(huán)指定的次數。
- class range(stop)?
- class range(start, stop[, step])
The arguments to the range constructor must be integers (either built-in
int
or any object that implements the__index__()
special method). If the step argument is omitted, it defaults to1
. If the start argument is omitted, it defaults to0
. If step is zero,ValueError
is raised.如果 step 為正值,確定 range
r
內容的公式為r[i] = start + step*i
其中i >= 0
且r[i] < stop
。如果 step 為負值,確定 range 內容的公式仍然為
r[i] = start + step*i
,但限制條件改為i >= 0
且r[i] > stop
.如果
r[0]
不符合值的限制條件,則該 range 對象為空。 range 對象確實(shí)支持負索引,但是會(huì )將其解讀為從正索引所確定的序列的末尾開(kāi)始索引。元素絕對值大于
sys.maxsize
的 range 對象是被允許的,但某些特性 (例如len()
) 可能引發(fā)OverflowError
。一些 range 對象的例子:
>>> 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)) []
range 對象實(shí)現了 一般 序列的所有操作,但拼接和重復除外(這是由于 range 對象只能表示符合嚴格模式的序列,而重復和拼接通常都會(huì )違反這樣的模式)。
- start?
start 形參的值 (如果該形參未提供則為
0
)
- stop?
stop 形參的值
- step?
step 形參的值 (如果該形參未提供則為
1
)
range
類(lèi)型相比常規 list
或 tuple
的優(yōu)勢在于一個(gè) range
對象總是占用固定數量的(較?。﹥却?,不論其所表示的范圍有多大(因為它只保存了 start
, stop
和 step
值,并會(huì )根據需要計算具體單項或子范圍的值)。
range 對象實(shí)現了 collections.abc.Sequence
ABC,提供如包含檢測、元素索引查找、切片等特性,并支持負索引 (參見(jiàn) 序列類(lèi)型 --- 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
使用 ==
和 !=
檢測 range 對象是否相等是將其作為序列來(lái)比較。 也就是說(shuō),如果兩個(gè) range 對象表示相同的值序列就認為它們是相等的。 (請注意比較結果相等的兩個(gè) range 對象可能會(huì )具有不同的 start
, stop
和 step
屬性,例如 range(0) == range(2, 1, 3)
而 range(0, 3, 2) == range(0, 4, 2)
。)
在 3.2 版更改: 實(shí)現 Sequence ABC。 支持切片和負數索引。 使用 int
對象在固定時(shí)間內進(jìn)行成員檢測,而不是逐一迭代所有項。
在 3.3 版更改: 定義 '==' 和 '!=' 以根據 range 對象所定義的值序列來(lái)進(jìn)行比較(而不是根據對象的標識)。
參見(jiàn)
linspace recipe 演示了如何實(shí)現一個(gè)延遲求值版本的適合浮點(diǎn)數應用的 range 對象。
文本序列類(lèi)型 --- str
?
在 Python 中處理文本數據是使用 str
對象,也稱(chēng)為 字符串。 字符串是由 Unicode 碼位構成的不可變 序列。 字符串字面值有多種不同的寫(xiě)法:
單引號:
'允許包含有 "雙" 引號'
Double quotes:
"allows embedded 'single' quotes"
三重引號:
'''三重單引號'''
,"""三重雙引號"""
使用三重引號的字符串可以跨越多行 —— 其中所有的空白字符都將包含在該字符串字面值中。
作為單一表達式組成部分,之間只由空格分隔的多個(gè)字符串字面值會(huì )被隱式地轉換為單個(gè)字符串字面值。 也就是說(shuō),("spam " "eggs") == "spam eggs"
。
請參閱 字符串與字節串字面值 有解有關(guān)不同字符串字面值的更多信息,包括所支持的轉義序列,以及使用 r
("raw") 前綴來(lái)禁用大多數轉義序列的處理。
字符串也可以通過(guò)使用 str
構造器從其他對象創(chuàng )建。
由于不存在單獨的“字符”類(lèi)型,對字符串做索引操作將產(chǎn)生一個(gè)長(cháng)度為 1 的字符串。 也就是說(shuō),對于一個(gè)非空字符串 s, s[0] == s[0:1]
。
不存在可變的字符串類(lèi)型,但是 str.join()
或 io.StringIO
可以被被用來(lái)根據多個(gè)片段高效率地構建字符串。
在 3.3 版更改: 為了與 Python 2 系列的向下兼容,再次允許字符串字面值使用 u
前綴。 它對字符串字面值的含義沒(méi)有影響,并且不能與 r
前綴同時(shí)出現。
- class str(object='')?
- class str(object=b'', encoding='utf-8', errors='strict')
返回 object 的 字符串 版本。 如果未提供 object 則返回空字符串。 在其他情況下
str()
的行為取決于 encoding 或 errors 是否有給出,具體見(jiàn)下。If neither encoding nor errors is given,
str(object)
returnstype(object).__str__(object)
, which is the "informal" or nicely printable string representation of object. For string objects, this is the string itself. If object does not have a__str__()
method, thenstr()
falls back to returningrepr(object)
.如果 encoding 或 errors 至少給出其中之一,則 object 應該是一個(gè) bytes-like object (例如
bytes
或bytearray
)。 在此情況下,如果 object 是一個(gè)bytes
(或bytearray
) 對象,則str(bytes, encoding, errors)
等價(jià)于bytes.decode(encoding, errors)
。 否則的話(huà),會(huì )在調用bytes.decode()
之前獲取緩沖區對象下層的 bytes 對象。 請參閱 二進(jìn)制序列類(lèi)型 --- bytes, bytearray, memoryview 與 緩沖協(xié)議 了解有關(guān)緩沖區對象的信息。將一個(gè)
bytes
對象傳入str()
而不給出 encoding 或 errors 參數的操作屬于第一種情況, 將返回非正式的字符串表示(另請參閱 Python 的-b
命令行選項)。 例如:>>> str(b'Zoot!') "b'Zoot!'"
有關(guān)
str
類(lèi)及其方法的更多信息,請參閱下面的 文本序列類(lèi)型 --- str 和 字符串的方法 小節。 要輸出格式化字符串,請參閱 格式字符串字面值 和 格式字符串語(yǔ)法 小節。 此外還可以參閱 文本處理服務(wù) 小節。
字符串的方法?
字符串實(shí)現了所有 一般 序列的操作,還額外提供了以下列出的一些附加方法。
字符串還支持兩種字符串格式化樣式,一種提供了很大程度的靈活性和可定制性 (參閱 str.format()
, 格式字符串語(yǔ)法 和 自定義字符串格式化) 而另一種是基于 C printf
樣式的格式化,它可處理的類(lèi)型范圍較窄,并且更難以正確使用,但對于它可處理的情況往往會(huì )更為快速 (printf 風(fēng)格的字符串格式化)。
標準庫的 文本處理服務(wù) 部分涵蓋了許多其他模塊,提供各種文本相關(guān)工具(例如包含于 re
模塊中的正則表達式支持)。
- str.capitalize()?
返回原字符串的副本,其首個(gè)字符大寫(xiě),其余為小寫(xiě)。
在 3.8 版更改: 第一個(gè)字符現在被放入了 titlecase 而不是 uppercase。 這意味著(zhù)復合字母類(lèi)字符將只有首個(gè)字母改為大寫(xiě),而再不是全部字符大寫(xiě)。
- str.casefold()?
返回原字符串消除大小寫(xiě)的副本。 消除大小寫(xiě)的字符串可用于忽略大小寫(xiě)的匹配。
消除大小寫(xiě)類(lèi)似于轉為小寫(xiě),但是更加徹底一些,因為它會(huì )移除字符串中的所有大小寫(xiě)變化形式。 例如,德語(yǔ)小寫(xiě)字母
'?'
相當于"ss"
。 由于它已經(jīng)是小寫(xiě)了,lower()
不會(huì )對'?'
做任何改變;而casefold()
則會(huì )將其轉換為"ss"
。消除大小寫(xiě)算法的描述請參見(jiàn) Unicode 標準的 3.13 節。
3.3 新版功能.
- str.center(width[, fillchar])?
返回長(cháng)度為 width 的字符串,原字符串在其正中。 使用指定的 fillchar 填充兩邊的空位(默認使用 ASCII 空格符)。 如果 width 小于等于
len(s)
則返回原字符串的副本。
- str.count(sub[, start[, end]])?
返回子字符串 sub 在 [start, end] 范圍內非重疊出現的次數。 可選參數 start 與 end 會(huì )被解讀為切片表示法。
- str.encode(encoding='utf-8', errors='strict')?
返回原字符串編碼為字節串對象的版本。 默認編碼為
'utf-8'
。 可以給出 errors 來(lái)設置不同的錯誤處理方案。 errors 的默認值為'strict'
,表示編碼錯誤會(huì )引發(fā)UnicodeError
。 其他可用的值為'ignore'
,'replace'
,'xmlcharrefreplace'
,'backslashreplace'
以及任何其他通過(guò)codecs.register_error()
注冊的值,請參閱 錯誤處理方案 小節。 要查看可用的編碼列表,請參閱 標準編碼 小節。默認情況下,為了獲得最佳性能,不會(huì )檢測 errors 參數,而只在首次編碼錯誤時(shí)用到它。若要檢測 errors ,請啟用 Python開(kāi)發(fā)模式 或用 調試版本 。
在 3.1 版更改: 加入了對關(guān)鍵字參數的支持。
在 3.9 版更改: 現在,僅在開(kāi)發(fā)模式和 調試模式 下才會(huì )檢測 errors。
- str.endswith(suffix[, start[, end]])?
如果字符串以指定的 suffix 結束返回
True
,否則返回False
。 suffix 也可以為由多個(gè)供查找的后綴構成的元組。 如果有可選項 start,將從所指定位置開(kāi)始檢查。 如果有可選項 end,將在所指定位置停止比較。
- str.expandtabs(tabsize=8)?
返回字符串的副本,其中所有的制表符會(huì )由一個(gè)或多個(gè)空格替換,具體取決于當前列位置和給定的制表符寬度。 每 tabsize 個(gè)字符設為一個(gè)制表位(默認值 8 時(shí)設定的制表位在列 0, 8, 16 依次類(lèi)推)。 要展開(kāi)字符串,當前列將被設為零并逐一檢查字符串中的每個(gè)字符。 如果字符為制表符 (
\t
),則會(huì )在結果中插入一個(gè)或多個(gè)空格符,直到當前列等于下一個(gè)制表位。 (制表符本身不會(huì )被復制。) 如果字符為換行符 (\n
) 或回車(chē)符 (\r
),它會(huì )被復制并將當前列重設為零。 任何其他字符會(huì )被不加修改地復制并將當前列加一,不論該字符在被打印時(shí)會(huì )如何顯示。>>> '01\t012\t0123\t01234'.expandtabs() '01 012 0123 01234' >>> '01\t012\t0123\t01234'.expandtabs(4) '01 012 0123 01234'
- str.find(sub[, start[, end]])?
返回子字符串 sub 在
s[start:end]
切片內被找到的最小索引。 可選參數 start 與 end 會(huì )被解讀為切片表示法。 如果 sub 未被找到則返回-1
。
- str.format(*args, **kwargs)?
執行字符串格式化操作。 調用此方法的字符串可以包含字符串字面值或者以花括號
{}
括起來(lái)的替換域。 每個(gè)替換域可以包含一個(gè)位置參數的數字索引,或者一個(gè)關(guān)鍵字參數的名稱(chēng)。 返回的字符串副本中每個(gè)替換域都會(huì )被替換為對應參數的字符串值。>>> "The sum of 1 + 2 is {0}".format(1+2) 'The sum of 1 + 2 is 3'
請參閱 格式字符串語(yǔ)法 了解有關(guān)可以在格式字符串中指定的各種格式選項的說(shuō)明。
備注
當使用
n
類(lèi)型 (例如:'{:n}'.format(1234)
) 來(lái)格式化數字 (int
,float
,complex
,decimal.Decimal
及其子類(lèi)) 的時(shí)候,該函數會(huì )臨時(shí)性地將LC_CTYPE
區域設置為LC_NUMERIC
區域以解碼localeconv()
的decimal_point
和thousands_sep
字段,如果它們是非 ASCII 字符或長(cháng)度超過(guò) 1 字節的話(huà),并且LC_NUMERIC
區域會(huì )與LC_CTYPE
區域不一致。 這個(gè)臨時(shí)更改會(huì )影響其他線(xiàn)程。在 3.7 版更改: 當使用
n
類(lèi)型格式化數字時(shí),該函數在某些情況下會(huì )臨時(shí)性地將LC_CTYPE
區域設置為LC_NUMERIC
區域。
- str.format_map(mapping)?
類(lèi)似于
str.format(**mapping)
,不同之處在于mapping
會(huì )被直接使用而不是復制到一個(gè)dict
。 適宜使用此方法的一個(gè)例子是當mapping
為 dict 的子類(lèi)的情況:>>> 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]])?
類(lèi)似于
find()
,但在找不到子字符串時(shí)會(huì )引發(fā)ValueError
。
- str.isalnum()?
如果字符串中的所有字符都是字母或數字且至少有一個(gè)字符,則返回
True
, 否則返回False
。 如果c.isalpha()
,c.isdecimal()
,c.isdigit()
,或c.isnumeric()
之中有一個(gè)返回True
,則字符``c``是字母或數字。
- str.isalpha()?
如果字符串中的所有字符都是字母,并且至少有一個(gè)字符,返回
True
,否則返回False
。字母字符是指那些在 Unicode 字符數據庫中定義為 "Letter" 的字符,即那些具有 "Lm"、"Lt"、"Lu"、"Ll" 或 "Lo" 之一的通用類(lèi)別屬性的字符。 注意,這與 Unicode 標準中定義的"字母"屬性不同。
- str.isascii()?
如果字符串為空或字符串中的所有字符都是 ASCII ,返回
True
,否則返回False
。ASCII 字符的碼點(diǎn)范圍是 U+0000-U+007F 。3.7 新版功能.
- str.isdecimal()?
如果字符串中的所有字符都是十進(jìn)制字符且該字符串至少有一個(gè)字符,則返回
True
, 否則返回False
。十進(jìn)制字符指那些可以用來(lái)組成10進(jìn)制數字的字符,例如 U+0660 ,即阿拉伯字母數字0 。 嚴格地講,十進(jìn)制字符是 Unicode 通用類(lèi)別 "Nd" 中的一個(gè)字符。
- str.isdigit()?
如果字符串中的所有字符都是數字,并且至少有一個(gè)字符,返回
True
,否則返回False
。 數字包括十進(jìn)制字符和需要特殊處理的數字,如兼容性上標數字。這包括了不能用來(lái)組成 10 進(jìn)制數的數字,如 Kharosthi 數。 嚴格地講,數字是指屬性值為 Numeric_Type=Digit 或 Numeric_Type=Decimal 的字符。
- str.isidentifier()?
如果字符串是有效的標識符,返回
True
,依據語(yǔ)言定義, 標識符和關(guān)鍵字 節。調用
keyword.iskeyword()
來(lái)檢測字符串s
是否為保留標識符,例如def
和class
。示例:
>>> from keyword import iskeyword >>> 'hello'.isidentifier(), iskeyword('hello') (True, False) >>> 'def'.isidentifier(), iskeyword('def') (True, True)
- str.isnumeric()?
如果字符串中至少有一個(gè)字符且所有字符均為數值字符則返回
True
,否則返回False
。 數值字符包括數字字符,以及所有在 Unicode 中設置了數值特性屬性的字符,例如 U+2155, VULGAR FRACTION ONE FIFTH。 正式的定義為:數值字符就是具有特征屬性值 Numeric_Type=Digit, Numeric_Type=Decimal 或 Numeric_Type=Numeric 的字符。
- str.isprintable()?
如果字符串中所有字符均為可打印字符或字符串為空則返回
True
,否則返回False
。 不可打印字符是在 Unicode 字符數據庫中被定義為 "Other" 或 "Separator" 的字符,例外情況是 ASCII 空格字符 (0x20) 被視作可打印字符。 (請注意在此語(yǔ)境下可打印字符是指當對一個(gè)字符串發(fā)起調用repr()
時(shí)不必被轉義的字符。 它們與字符串寫(xiě)入sys.stdout
或sys.stderr
時(shí)所需的處理無(wú)關(guān)。)
- str.isspace()?
如果字符串中只有空白字符且至少有一個(gè)字符則返回
True
,否則返回False
。空白 字符是指在 Unicode 字符數據庫 (參見(jiàn)
unicodedata
) 中主要類(lèi)別為Zs
("Separator, space") 或所屬雙向類(lèi)為WS
,B
或S
的字符。
- str.istitle()?
如果字符串中至少有一個(gè)字符且為標題字符串則返回
True
,例如大寫(xiě)字符之后只能帶非大寫(xiě)字符而小寫(xiě)字符必須有大寫(xiě)字符打頭。 否則返回False
。
- str.isupper()?
如果字符串中至少有一個(gè)區分大小寫(xiě)的字符 4 且此類(lèi)字符均為大寫(xiě)則返回
True
,否則返回False
。>>> 'BANANA'.isupper() True >>> 'banana'.isupper() False >>> 'baNana'.isupper() False >>> ' '.isupper() False
- str.join(iterable)?
返回一個(gè)由 iterable 中的字符串拼接而成的字符串。 如果 iterable 中存在任何非字符串值包括
bytes
對象則會(huì )引發(fā)TypeError
。 調用該方法的字符串將作為元素之間的分隔。
- str.ljust(width[, fillchar])?
返回長(cháng)度為 width 的字符串,原字符串在其中靠左對齊。 使用指定的 fillchar 填充空位 (默認使用 ASCII 空格符)。 如果 width 小于等于
len(s)
則返回原字符串的副本。
- str.lower()?
返回原字符串的副本,其所有區分大小寫(xiě)的字符 4 均轉換為小寫(xiě)。
所用轉換小寫(xiě)算法的描述請參見(jiàn) Unicode 標準的 3.13 節。
- str.lstrip([chars])?
返回原字符串的副本,移除其中的前導字符。 chars 參數為指定要移除字符的字符串。 如果省略或為
None
,則 chars 參數默認移除空白符。 實(shí)際上 chars 參數并非指定單個(gè)前綴;而是會(huì )移除參數值的所有組合:>>> ' spacious '.lstrip() 'spacious ' >>> 'www.example.com'.lstrip('cmowz.') 'example.com'
參見(jiàn)
str.removeprefix()
,該方法將刪除單個(gè)前綴字符串,而不是全部給定集合中的字符。 例如:>>> 'Arthur: three!'.lstrip('Arthur: ') 'ee!' >>> 'Arthur: three!'.removeprefix('Arthur: ') 'three!'
- static str.maketrans(x[, y[, z]])?
此靜態(tài)方法返回一個(gè)可供
str.translate()
使用的轉換對照表。如果只有一個(gè)參數,則它必須是一個(gè)將 Unicode 碼位序號(整數)或字符(長(cháng)度為 1 的字符串)映射到 Unicode 碼位序號、(任意長(cháng)度的)字符串或
None
的字典。 字符鍵將會(huì )被轉換為碼位序號。如果有兩個(gè)參數,則它們必須是兩個(gè)長(cháng)度相等的字符串,并且在結果字典中,x 中每個(gè)字符將被映射到 y 中相同位置的字符。 如果有第三個(gè)參數,它必須是一個(gè)字符串,其中的字符將在結果中被映射到
None
。
- str.partition(sep)?
在 sep 首次出現的位置拆分字符串,返回一個(gè) 3 元組,其中包含分隔符之前的部分、分隔符本身,以及分隔符之后的部分。 如果分隔符未找到,則返回的 3 元組中包含字符本身以及兩個(gè)空字符串。
- str.removeprefix(prefix, /)?
如果字符串以 前綴 字符串開(kāi)頭,返回
string[len(prefix):]
。否則,返回原始字符串的副本:>>> 'TestHook'.removeprefix('Test') 'Hook' >>> 'BaseTestCase'.removeprefix('Test') 'BaseTestCase'
3.9 新版功能.
- str.removesuffix(suffix, /)?
如果字符串以 后綴 字符串結尾,并且 后綴 非空,返回
string[:-len(suffix)]
。否則,返回原始字符串的副本:>>> 'MiscTests'.removesuffix('Tests') 'Misc' >>> 'TmpDirMixin'.removesuffix('Tests') 'TmpDirMixin'
3.9 新版功能.
- str.replace(old, new[, count])?
返回字符串的副本,其中出現的所有子字符串 old 都將被替換為 new。 如果給出了可選參數 count,則只替換前 count 次出現。
- str.rfind(sub[, start[, end]])?
返回子字符串 sub 在字符串內被找到的最大(最右)索引,這樣 sub 將包含在
s[start:end]
當中。 可選參數 start 與 end 會(huì )被解讀為切片表示法。 如果未找到則返回-1
。
- str.rindex(sub[, start[, end]])?
類(lèi)似于
rfind()
,但在子字符串 sub 未找到時(shí)會(huì )引發(fā)ValueError
。
- str.rjust(width[, fillchar])?
返回長(cháng)度為 width 的字符串,原字符串在其中靠右對齊。 使用指定的 fillchar 填充空位 (默認使用 ASCII 空格符)。 如果 width 小于等于
len(s)
則返回原字符串的副本。
- str.rpartition(sep)?
在 sep 最后一次出現的位置拆分字符串,返回一個(gè) 3 元組,其中包含分隔符之前的部分、分隔符本身,以及分隔符之后的部分。 如果分隔符未找到,則返回的 3 元組中包含兩個(gè)空字符串以及字符串本身。
- str.rsplit(sep=None, maxsplit=- 1)?
返回一個(gè)由字符串內單詞組成的列表,使用 sep 作為分隔字符串。 如果給出了 maxsplit,則最多進(jìn)行 maxsplit 次拆分,從 最右邊 開(kāi)始。 如果 sep 未指定或為
None
,任何空白字符串都會(huì )被作為分隔符。 除了從右邊開(kāi)始拆分,rsplit()
的其他行為都類(lèi)似于下文所述的split()
。
- str.rstrip([chars])?
返回原字符串的副本,移除其中的末尾字符。 chars 參數為指定要移除字符的字符串。 如果省略或為
None
,則 chars 參數默認移除空白符。 實(shí)際上 chars 參數并非指定單個(gè)后綴;而是會(huì )移除參數值的所有組合:>>> ' spacious '.rstrip() ' spacious' >>> 'mississippi'.rstrip('ipz') 'mississ'
要刪除單個(gè)后綴字符串,而不是全部給定集合中的字符,請參見(jiàn)
str.removesuffix()
方法。 例如:>>> 'Monty Python'.rstrip(' Python') 'M' >>> 'Monty Python'.removesuffix(' Python') 'Monty'
- str.split(sep=None, maxsplit=- 1)?
返回一個(gè)由字符串內單詞組成的列表,使用 sep 作為分隔字符串。 如果給出了 maxsplit,則最多進(jìn)行 maxsplit 次拆分(因此,列表最多會(huì )有
maxsplit+1
個(gè)元素)。 如果 maxsplit 未指定或為-1
,則不限制拆分次數(進(jìn)行所有可能的拆分)。如果給出了 sep,則連續的分隔符不會(huì )被組合在一起而是被視為分隔空字符串 (例如
'1,,2'.split(',')
將返回['1', '', '2']
)。 sep 參數可能由多個(gè)字符組成 (例如'1<>2<>3'.split('<>')
將返回['1', '2', '3']
)。 使用指定的分隔符拆分空字符串將返回['']
。例如:
>>> '1,2,3'.split(',') ['1', '2', '3'] >>> '1,2,3'.split(',', maxsplit=1) ['1', '2,3'] >>> '1,2,,3,'.split(',') ['1', '2', '', '3', '']
如果 sep 未指定或為
None
,則會(huì )應用另一種拆分算法:連續的空格會(huì )被視為單個(gè)分隔符,其結果將不包含開(kāi)頭或末尾的空字符串,如果字符串包含前綴或后綴空格的話(huà)。 因此,使用None
拆分空字符串或僅包含空格的字符串將返回[]
。例如:
>>> '1 2 3'.split() ['1', '2', '3'] >>> '1 2 3'.split(maxsplit=1) ['1', '2 3'] >>> ' 1 2 3 '.split() ['1', '2', '3']
- str.splitlines(keepends=False)?
返回由原字符串中各行組成的列表,在行邊界的位置拆分。 結果列表中不包含行邊界,除非給出了 keepends 且為真值。
此方法會(huì )以下列行邊界進(jìn)行拆分。 特別地,行邊界是 universal newlines 的一個(gè)超集。
表示符
描述
\n
換行
\r
回車(chē)
\r\n
回車(chē) + 換行
\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']
不同于
split()
,當給出了分隔字符串 sep 時(shí),對于空字符串此方法將返回一個(gè)空列表,而末尾的換行不會(huì )令結果中增加額外的行:>>> "".splitlines() [] >>> "One line\n".splitlines() ['One line']
作為比較,
split('\n')
的結果為:>>> ''.split('\n') [''] >>> 'Two lines\n'.split('\n') ['Two lines', '']
- str.startswith(prefix[, start[, end]])?
如果字符串以指定的 prefix 開(kāi)始則返回
True
,否則返回False
。 prefix 也可以為由多個(gè)供查找的前綴構成的元組。 如果有可選項 start,將從所指定位置開(kāi)始檢查。 如果有可選項 end,將在所指定位置停止比較。
- str.strip([chars])?
返回原字符串的副本,移除其中的前導和末尾字符。 chars 參數為指定要移除字符的字符串。 如果省略或為
None
,則 chars 參數默認移除空白符。 實(shí)際上 chars 參數并非指定單個(gè)前綴或后綴;而是會(huì )移除參數值的所有組合:>>> ' spacious '.strip() 'spacious' >>> 'www.example.com'.strip('cmowz.') 'example'
最外側的前導和末尾 chars 參數值將從字符串中移除。 開(kāi)頭端的字符的移除將在遇到一個(gè)未包含于 chars 所指定字符集的字符時(shí)停止。 類(lèi)似的操作也將在結尾端發(fā)生。 例如:
>>> comment_string = '#....... Section 3.2.1 Issue #32 .......' >>> comment_string.strip('.#! ') 'Section 3.2.1 Issue #32'
- str.swapcase()?
返回原字符串的副本,其中大寫(xiě)字符轉換為小寫(xiě),反之亦然。 請注意
s.swapcase().swapcase() == s
并不一定為真值。
- str.title()?
返回原字符串的標題版本,其中每個(gè)單詞第一個(gè)字母為大寫(xiě),其余字母為小寫(xiě)。
例如:
>>> 'Hello world'.title() 'Hello World'
該算法使用一種簡(jiǎn)單的與語(yǔ)言無(wú)關(guān)的定義,將連續的字母組合視為單詞。 該定義在多數情況下都很有效,但它也意味著(zhù)代表縮寫(xiě)形式與所有格的撇號也會(huì )成為單詞邊界,這可能導致不希望的結果:
>>> "they're bill's friends from the UK".title() "They'Re Bill'S Friends From The Uk"
The
string.capwords()
function does not have this problem, as it splits words on spaces only.Alternatively, a workaround for apostrophes can be constructed using regular expressions:
>>> 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."
- str.translate(table)?
返回原字符串的副本,其中每個(gè)字符按給定的轉換表進(jìn)行映射。 轉換表必須是一個(gè)使用
__getitem__()
來(lái)實(shí)現索引操作的對象,通常為 mapping 或 sequence。 當以 Unicode 碼位序號(整數)為索引時(shí),轉換表對象可以做以下任何一種操作:返回 Unicode 序號或字符串,將字符映射為一個(gè)或多個(gè)字符;返回None
,將字符從結果字符串中刪除;或引發(fā)LookupError
異常,將字符映射為其自身。你可以使用
str.maketrans()
基于不同格式的字符到字符映射來(lái)創(chuàng )建一個(gè)轉換映射表。另請參閱
codecs
模塊以了解定制字符映射的更靈活方式。
- str.upper()?
返回原字符串的副本,其中所有區分大小寫(xiě)的字符 4 均轉換為大寫(xiě)。 請注意如果
s
包含不區分大小寫(xiě)的字符或者如果結果字符的 Unicode 類(lèi)別不是 "Lu" (Letter, uppercase) 而是 "Lt" (Letter, titlecase) 則s.upper().isupper()
有可能為False
。所用轉換大寫(xiě)算法的描述請參見(jiàn) Unicode 標準的 3.13 節。
- str.zfill(width)?
返回原字符串的副本,在左邊填充 ASCII
'0'
數碼使其長(cháng)度變?yōu)?width。 正負值前綴 ('+'
/'-'
) 的處理方式是在正負符號 之后 填充而非在之前。 如果 width 小于等于len(s)
則返回原字符串的副本。例如:
>>> "42".zfill(5) '00042' >>> "-42".zfill(5) '-0042'
printf
風(fēng)格的字符串格式化?
備注
此處介紹的格式化操作具有多種怪異特性,可能導致許多常見(jiàn)錯誤(例如無(wú)法正確顯示元組和字典)。 使用較新的 格式化字符串字面值,str.format()
接口或 模板字符串 有助于避免這樣的錯誤。 這些替代方案中的每一種都更好地權衡并提供了簡(jiǎn)單、靈活以及可擴展性?xún)?yōu)勢。
字符串具有一種特殊的內置操作:使用 %
(取模) 運算符。 這也被稱(chēng)為字符串的 格式化 或 插值 運算符。 對于 format % values
(其中 format 為一個(gè)字符串),在 format 中的 %
轉換標記符將被替換為零個(gè)或多個(gè) values 條目。 其效果類(lèi)似于在 C 語(yǔ)言中使用 sprintf()
。
如果 format 要求一個(gè)單獨參數,則 values 可以為一個(gè)非元組對象。 5 否則的話(huà),values 必須或者是一個(gè)包含項數與格式字符串中指定的轉換符項數相同的元組,或者是一個(gè)單獨映射對象(例如字典)。
轉換標記符包含兩個(gè)或更多字符并具有以下組成,且必須遵循此處規定的順序:
'%'
字符,用于標記轉換符的起始。映射鍵(可選),由加圓括號的字符序列組成 (例如
(somename)
)。轉換旗標(可選),用于影響某些轉換類(lèi)型的結果。
最小字段寬度(可選)。 如果指定為
'*'
(星號),則實(shí)際寬度會(huì )從 values 元組的下一元素中讀取,要轉換的對象則為最小字段寬度和可選的精度之后的元素。精度(可選),以在
'.'
(點(diǎn)號) 之后加精度值的形式給出。 如果指定為'*'
(星號),則實(shí)際精度會(huì )從 values 元組的下一元素中讀取,要轉換的對象則為精度之后的元素。長(cháng)度修飾符(可選)。
轉換類(lèi)型。
當右邊的參數為一個(gè)字典(或其他映射類(lèi)型)時(shí),字符串中的格式 必須 包含加圓括號的映射鍵,對應 '%'
字符之后字典中的每一項。 映射鍵將從映射中選取要格式化的值。 例如:
>>> print('%(language)s has %(number)03d quote types.' %
... {'language': "Python", "number": 2})
Python has 002 quote types.
在此情況下格式中不能出現 *
標記符(因其需要一個(gè)序列類(lèi)的參數列表)。
轉換旗標為:
旗標 |
含意 |
---|---|
|
值的轉換將使用“替代形式”(具體定義見(jiàn)下文)。 |
|
轉換將為數字值填充零字符。 |
|
轉換值將靠左對齊(如果同時(shí)給出 |
|
(空格) 符號位轉換產(chǎn)生的正數(或空字符串)前將留出一個(gè)空格。 |
|
符號字符 ( |
可以給出長(cháng)度修飾符 (h
, l
或 L
),但會(huì )被忽略,因為對 Python 來(lái)說(shuō)沒(méi)有必要 -- 所以 %ld
等價(jià)于 %d
。
轉換類(lèi)型為:
轉換符 |
含意 |
備注 |
---|---|---|
|
有符號十進(jìn)制整數。 |
|
|
有符號十進(jìn)制整數。 |
|
|
有符號八進(jìn)制數。 |
(1) |
|
過(guò)時(shí)類(lèi)型 -- 等價(jià)于 |
(6) |
|
有符號十六進(jìn)制數(小寫(xiě))。 |
(2) |
|
有符號十六進(jìn)制數(大寫(xiě))。 |
(2) |
|
浮點(diǎn)指數格式(小寫(xiě))。 |
(3) |
|
浮點(diǎn)指數格式(大寫(xiě))。 |
(3) |
|
浮點(diǎn)十進(jìn)制格式。 |
(3) |
|
浮點(diǎn)十進(jìn)制格式。 |
(3) |
|
浮點(diǎn)格式。 如果指數小于 -4 或不小于精度則使用小寫(xiě)指數格式,否則使用十進(jìn)制格式。 |
(4) |
|
浮點(diǎn)格式。 如果指數小于 -4 或不小于精度則使用大寫(xiě)指數格式,否則使用十進(jìn)制格式。 |
(4) |
|
單個(gè)字符(接受整數或單個(gè)字符的字符串)。 |
|
|
字符串(使用 |
(5) |
|
字符串(使用 |
(5) |
|
字符串(使用 |
(5) |
|
不轉換參數,在結果中輸出一個(gè) |
注釋?zhuān)?/p>
此替代形式會(huì )在第一個(gè)數碼之前插入標示八進(jìn)制數的前綴 (
'0o'
)。此替代形式會(huì )在第一個(gè)數碼之前插入
'0x'
或'0X'
前綴(取決于是使用'x'
還是'X'
格式)。此替代形式總是會(huì )在結果中包含一個(gè)小數點(diǎn),即使其后并沒(méi)有數碼。
小數點(diǎn)后的數碼位數由精度決定,默認為 6。
此替代形式總是會(huì )在結果中包含一個(gè)小數點(diǎn),末尾各位的零不會(huì )如其他情況下那樣被移除。
小數點(diǎn)前后的有效數碼位數由精度決定,默認為 6。
如果精度為
N
,輸出將截短為N
個(gè)字符。參見(jiàn) PEP 237。
由于 Python 字符串顯式指明長(cháng)度,%s
轉換不會(huì )將 '\0'
視為字符串的結束。
在 3.1 版更改: 絕對值超過(guò) 1e50 的 %f
轉換不會(huì )再被替換為 %g
轉換。
二進(jìn)制序列類(lèi)型 --- bytes
, bytearray
, memoryview
?
操作二進(jìn)制數據的核心內置類(lèi)型是 bytes
和 bytearray
。 它們由 memoryview
提供支持,該對象使用 緩沖區協(xié)議 來(lái)訪(fǎng)問(wèn)其他二進(jìn)制對象所在內存,不需要創(chuàng )建對象的副本。
array
模塊支持高效地存儲基本數據類(lèi)型,例如 32 位整數和 IEEE754 雙精度浮點(diǎn)值。
bytes 對象?
bytes 對象是由單個(gè)字節構成的不可變序列。 由于許多主要二進(jìn)制協(xié)議都基于 ASCII 文本編碼,因此 bytes 對象提供了一些僅在處理 ASCII 兼容數據時(shí)可用,并且在許多特性上與字符串對象緊密相關(guān)的方法。
- class bytes([source[, encoding[, errors]]])?
首先,表示 bytes 字面值的語(yǔ)法與字符串字面值的大致相同,只是添加了一個(gè)
b
前綴:單引號:
b'同樣允許嵌入 "雙" 引號'
。Double quotes:
b"still allows embedded 'single' quotes"
三重引號:
b'''三重單引號'''
,b"""三重雙引號"""
bytes 字面值中只允許 ASCII 字符(無(wú)論源代碼聲明的編碼為何)。 任何超出 127 的二進(jìn)制值必須使用相應的轉義序列形式加入 bytes 字面值。
像字符串字面值一樣,bytes 字面值也可以使用
r
前綴來(lái)禁用轉義序列處理。 請參閱 字符串與字節串字面值 了解有關(guān)各種 bytes 字面值形式的詳情,包括所支持的轉義序列。雖然 bytes 字面值和表示法是基于 ASCII 文本的,但 bytes 對象的行為實(shí)際上更像是不可變的整數序列,序列中的每個(gè)值的大小被限制為
0 <= x < 256
(如果違反此限制將引發(fā)ValueError
)。 這種限制是有意設計用以強調以下事實(shí),雖然許多二進(jìn)制格式都包含基于 ASCII 的元素,可以通過(guò)某些面向文本的算法進(jìn)行有用的操作,但情況對于任意二進(jìn)制數據來(lái)說(shuō)通常卻并非如此(盲目地將文本處理算法應用于不兼容 ASCII 的二進(jìn)制數據格式往往將導致數據損壞)。除了字面值形式,bytes 對象還可以通過(guò)其他幾種方式來(lái)創(chuàng )建:
指定長(cháng)度的以零值填充的 bytes 對象:
bytes(10)
通過(guò)由整數組成的可迭代對象:
bytes(range(20))
通過(guò)緩沖區協(xié)議復制現有的二進(jìn)制數據:
bytes(obj)
另請參閱 bytes 內置類(lèi)型。
由于兩個(gè)十六進(jìn)制數碼精確對應一個(gè)字節,因此十六進(jìn)制數是描述二進(jìn)制數據的常用格式。 相應地,bytes 類(lèi)型具有從此種格式讀取數據的附加類(lèi)方法:
- classmethod fromhex(string)?
此
bytes
類(lèi)方法返回一個(gè)解碼給定字符串的 bytes 對象。 字符串必須由表示每個(gè)字節的兩個(gè)十六進(jìn)制數碼構成,其中的 ASCII 空白符會(huì )被忽略。>>> bytes.fromhex('2Ef0 F1f2 ') b'.\xf0\xf1\xf2'
在 3.7 版更改:
bytes.fromhex()
現在會(huì )忽略所有 ASCII 空白符而不只是空格符。
存在一個(gè)反向轉換函數,可以將 bytes 對象轉換為對應的十六進(jìn)制表示。
- hex([sep[, bytes_per_sep]])?
返回一個(gè)字符串對象,該對象包含實(shí)例中每個(gè)字節的兩個(gè)十六進(jìn)制數字。
>>> b'\xf0\xf1\xf2'.hex() 'f0f1f2'
如果你希望令十六進(jìn)制數字符串更易讀,你可以指定單個(gè)字符分隔符作為 sep 形參包含于輸出中。 默認會(huì )放在每個(gè)字節之間。 第二個(gè)可選的 bytes_per_sep 形參控制間距。 正值會(huì )從右開(kāi)始計算分隔符的位置,負值則是從左開(kāi)始。
>>> 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()
現在支持可選的 sep 和 bytes_per_sep 形參以在十六進(jìn)制輸出的字節之間插入分隔符。
由于 bytes 對象是由整數構成的序列(類(lèi)似于元組),因此對于一個(gè) bytes 對象 b,b[0]
將為一個(gè)整數,而 b[0:1]
將為一個(gè)長(cháng)度為 1 的 bytes 對象。 (這與文本字符串不同,索引和切片所產(chǎn)生的將都是一個(gè)長(cháng)度為 1 的字符串)。
bytes 對象的表示使用字面值格式 (b'...'
),因為它通常都要比像 bytes([46, 46, 46])
這樣的格式更好用。 你總是可以使用 list(b)
將 bytes 對象轉換為一個(gè)由整數構成的列表。
bytearray 對象?
- class bytearray([source[, encoding[, errors]]])?
bytearray 對象沒(méi)有專(zhuān)屬的字面值語(yǔ)法,它們總是通過(guò)調用構造器來(lái)創(chuàng )建:
創(chuàng )建一個(gè)空實(shí)例:
bytearray()
創(chuàng )建一個(gè)指定長(cháng)度的以零值填充的實(shí)例:
bytearray(10)
通過(guò)由整數組成的可迭代對象:
bytearray(range(20))
通過(guò)緩沖區協(xié)議復制現有的二進(jìn)制數據:
bytearray(b'Hi!')
由于 bytearray 對象是可變的,該對象除了 bytes 和 bytearray 操作 中所描述的 bytes 和 bytearray 共有操作之外,還支持 可變 序列操作。
另請參見(jiàn) bytearray 內置類(lèi)型。
由于兩個(gè)十六進(jìn)制數碼精確對應一個(gè)字節,因此十六進(jìn)制數是描述二進(jìn)制數據的常用格式。 相應地,bytearray 類(lèi)型具有從此種格式讀取數據的附加類(lèi)方法:
- classmethod fromhex(string)?
bytearray
類(lèi)方法返回一個(gè)解碼給定字符串的 bytearray 對象。 字符串必須由表示每個(gè)字節的兩個(gè)十六進(jìn)制數碼構成,其中的 ASCII 空白符會(huì )被忽略。>>> bytearray.fromhex('2Ef0 F1f2 ') bytearray(b'.\xf0\xf1\xf2')
在 3.7 版更改:
bytearray.fromhex()
現在會(huì )忽略所有 ASCII 空白符而不只是空格符。
存在一個(gè)反向轉換函數,可以將 bytearray 對象轉換為對應的十六進(jìn)制表示。
- hex([sep[, bytes_per_sep]])?
返回一個(gè)字符串對象,該對象包含實(shí)例中每個(gè)字節的兩個(gè)十六進(jìn)制數字。
>>> bytearray(b'\xf0\xf1\xf2').hex() 'f0f1f2'
3.5 新版功能.
在 3.8 版更改: 與
bytes.hex()
相似,bytearray.hex()
現在支持可選的 sep 和 bytes_per_sep 參數以在十六進(jìn)制輸出的字節之間插入分隔符。
由于 bytearray 對象是由整數構成的序列(類(lèi)似于列表),因此對于一個(gè) bytearray 對象 b,b[0]
將為一個(gè)整數,而 b[0:1]
將為一個(gè)長(cháng)度為 1 的 bytearray 對象。 (這與文本字符串不同,索引和切片所產(chǎn)生的將都是一個(gè)長(cháng)度為 1 的字符串)。
bytearray 對象的表示使用 bytes 對象字面值格式 (bytearray(b'...')
),因為它通常都要比 bytearray([46, 46, 46])
這樣的格式更好用。 你總是可以使用 list(b)
將 bytearray 對象轉換為一個(gè)由整數構成的列表。
bytes 和 bytearray 操作?
bytes 和 bytearray 對象都支持 通用 序列操作。 它們不僅能與相同類(lèi)型的操作數,也能與任何 bytes-like object 進(jìn)行互操作。 由于這樣的靈活性,它們可以在操作中自由地混合而不會(huì )導致錯誤。 但是,操作結果的返回值類(lèi)型可能取決于操作數的順序。
備注
bytes 和 bytearray 對象的方法不接受字符串作為其參數,就像字符串的方法不接受 bytes 對象作為其參數一樣。 例如,你必須使用以下寫(xiě)法:
a = "abc"
b = a.replace("a", "f")
和:
a = b"abc"
b = a.replace(b"a", b"f")
某些 bytes 和 bytearray 操作假定使用兼容 ASCII 的二進(jìn)制格式,因此在處理任意二進(jìn)數數據時(shí)應當避免使用。 這些限制會(huì )在下文中說(shuō)明。
備注
使用這些基于 ASCII 的操作來(lái)處理未以基于 ASCII 的格式存儲的二進(jìn)制數據可能會(huì )導致數據損壞。
bytes 和 bytearray 對象的下列方法可以用于任意二進(jìn)制數據。
- bytes.count(sub[, start[, end]])?
- bytearray.count(sub[, start[, end]])?
返回子序列 sub 在 [start, end] 范圍內非重疊出現的次數。 可選參數 start 與 end 會(huì )被解讀為切片表示法。
要搜索的子序列可以是任意 bytes-like object 或是 0 至 255 范圍內的整數。
在 3.3 版更改: 也接受 0 至 255 范圍內的整數作為子序列。
- bytes.removeprefix(prefix, /)?
- bytearray.removeprefix(prefix, /)?
如果二進(jìn)制數據以 前綴 字符串開(kāi)頭,返回
bytes[len(prefix):]
。否則,返回原始二進(jìn)制數據的副本:>>> b'TestHook'.removeprefix(b'Test') b'Hook' >>> b'BaseTestCase'.removeprefix(b'Test') b'BaseTestCase'
前綴可以是任意 bytes-like object。
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
3.9 新版功能.
- bytes.removesuffix(suffix, /)?
- bytearray.removesuffix(suffix, /)?
如果二進(jìn)制數據以 后綴 字符串結尾,并且 后綴 非空,返回
bytes[:-len(suffix)]
。否則,返回原始二進(jìn)制數據的副本:>>> b'MiscTests'.removesuffix(b'Tests') b'Misc' >>> b'TmpDirMixin'.removesuffix(b'Tests') b'TmpDirMixin'
后綴可以是任意 bytes-like object。
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
3.9 新版功能.
- bytes.decode(encoding='utf-8', errors='strict')?
- bytearray.decode(encoding='utf-8', errors='strict')?
返回從給定 bytes 解碼出來(lái)的字符串。 默認編碼為
'utf-8'
。 可以給出 errors 來(lái)設置不同的錯誤處理方案。 errors 的默認值為'strict'
,表示編碼錯誤會(huì )引發(fā)UnicodeError
。 其他可用的值為'ignore'
,'replace'
以及任何其他通過(guò)codecs.register_error()
注冊的名稱(chēng),請參閱 錯誤處理方案 小節。 要查看可用的編碼列表,請參閱 標準編碼 小節。默認情況下,為了獲得最佳性能,不會(huì )檢測 errors 參數,而只在首次編碼錯誤時(shí)用到它。若要檢測 errors ,請啟用 Python開(kāi)發(fā)模式 或用 調試版本 。
備注
將 encoding 參數傳給
str
允許直接解碼任何 bytes-like object,無(wú)須創(chuàng )建臨時(shí)的 bytes 或 bytearray 對象。在 3.1 版更改: 加入了對關(guān)鍵字參數的支持。
在 3.9 版更改: 現在,僅在開(kāi)發(fā)模式和 調試模式 下才會(huì )檢測 errors。
- bytes.endswith(suffix[, start[, end]])?
- bytearray.endswith(suffix[, start[, end]])?
如果二進(jìn)制數據以指定的 suffix 結束則返回
True
,否則返回False
。 suffix 也可以為由多個(gè)供查找的后綴構成的元組。 如果有可選項 start,將從所指定位置開(kāi)始檢查。 如果有可選項 end,將在所指定位置停止比較。要搜索的后綴可以是任意 bytes-like object。
- bytes.find(sub[, start[, end]])?
- bytearray.find(sub[, start[, end]])?
返回子序列 sub 在數據中被找到的最小索引,sub 包含于切片
s[start:end]
之內。 可選參數 start 與 end 會(huì )被解讀為切片表示法。 如果 sub 未被找到則返回-1
。要搜索的子序列可以是任意 bytes-like object 或是 0 至 255 范圍內的整數。
在 3.3 版更改: 也接受 0 至 255 范圍內的整數作為子序列。
- bytes.index(sub[, start[, end]])?
- bytearray.index(sub[, start[, end]])?
類(lèi)似于
find()
,但在找不到子序列時(shí)會(huì )引發(fā)ValueError
。要搜索的子序列可以是任意 bytes-like object 或是 0 至 255 范圍內的整數。
在 3.3 版更改: 也接受 0 至 255 范圍內的整數作為子序列。
- bytes.join(iterable)?
- bytearray.join(iterable)?
返回一個(gè)由 iterable 中的二進(jìn)制數據序列拼接而成的 bytes 或 bytearray 對象。 如果 iterable 中存在任何非 字節類(lèi)對象 包括存在
str
對象值則會(huì )引發(fā)TypeError
。 提供該方法的 bytes 或 bytearray 對象的內容將作為元素之間的分隔。
- static bytes.maketrans(from, to)?
- static bytearray.maketrans(from, to)?
此靜態(tài)方法返回一個(gè)可用于
bytes.translate()
的轉換對照表,它將把 from 中的每個(gè)字符映射為 to 中相同位置上的字符;from 與 to 必須都是 字節類(lèi)對象 并且具有相同的長(cháng)度。3.1 新版功能.
- bytes.partition(sep)?
- bytearray.partition(sep)?
在 sep 首次出現的位置拆分序列,返回一個(gè) 3 元組,其中包含分隔符之前的部分、分隔符本身或其 bytearray 副本,以及分隔符之后的部分。 如果分隔符未找到,則返回的 3 元組中包含原序列以及兩個(gè)空的 bytes 或 bytearray 對象。
要搜索的分隔符可以是任意 bytes-like object。
- bytes.replace(old, new[, count])?
- bytearray.replace(old, new[, count])?
返回序列的副本,其中出現的所有子序列 old 都將被替換為 new。 如果給出了可選參數 count,則只替換前 count 次出現。
要搜索的子序列及其替換序列可以是任意 bytes-like object。
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.rfind(sub[, start[, end]])?
- bytearray.rfind(sub[, start[, end]])?
返回子序列 sub 在序列內被找到的最大(最右)索引,這樣 sub 將包含在
s[start:end]
當中。 可選參數 start 與 end 會(huì )被解讀為切片表示法。 如果未找到則返回-1
。要搜索的子序列可以是任意 bytes-like object 或是 0 至 255 范圍內的整數。
在 3.3 版更改: 也接受 0 至 255 范圍內的整數作為子序列。
- bytes.rindex(sub[, start[, end]])?
- bytearray.rindex(sub[, start[, end]])?
類(lèi)似于
rfind()
,但在子序列 sub 未找到時(shí)會(huì )引發(fā)ValueError
。要搜索的子序列可以是任意 bytes-like object 或是 0 至 255 范圍內的整數。
在 3.3 版更改: 也接受 0 至 255 范圍內的整數作為子序列。
- bytes.rpartition(sep)?
- bytearray.rpartition(sep)?
在 sep 最后一次出現的位置拆分序列,返回一個(gè) 3 元組,其中包含分隔符之前的部分,分隔符本身或其 bytearray 副本,以及分隔符之后的部分。 如果分隔符未找到,則返回的 3 元組中包含兩個(gè)空的 bytes 或 bytearray 對象以及原序列的副本。
要搜索的分隔符可以是任意 bytes-like object。
- bytes.startswith(prefix[, start[, end]])?
- bytearray.startswith(prefix[, start[, end]])?
如果二進(jìn)制數據以指定的 prefix 開(kāi)頭則返回
True
,否則返回False
。 prefix 也可以為由多個(gè)供查找的前綴構成的元組。 如果有可選項 start,將從所指定位置開(kāi)始檢查。 如果有可選項 end,將在所指定位置停止比較。要搜索的前綴可以是任意 bytes-like object。
- bytes.translate(table, /, delete=b'')?
- bytearray.translate(table, /, delete=b'')?
返回原 bytes 或 bytearray 對象的副本,移除其中所有在可選參數 delete 中出現的 bytes,其余 bytes 將通過(guò)給定的轉換表進(jìn)行映射,該轉換表必須是長(cháng)度為 256 的 bytes 對象。
你可以使用
bytes.maketrans()
方法來(lái)創(chuàng )建轉換表。對于僅需移除字符的轉換,請將 table 參數設為
None
:>>> b'read this short text'.translate(None, b'aeiou') b'rd ths shrt txt'
在 3.6 版更改: 現在支持將 delete 作為關(guān)鍵字參數。
以下 bytes 和 bytearray 對象的方法的默認行為會(huì )假定使用兼容 ASCII 的二進(jìn)制格式,但通過(guò)傳入適當的參數仍然可用于任意二進(jìn)制數據。 請注意本小節中所有的 bytearray 方法都 不是 原地執行操作,而是會(huì )產(chǎn)生新的對象。
- bytes.center(width[, fillbyte])?
- bytearray.center(width[, fillbyte])?
返回原對象的副本,在長(cháng)度為 width 的序列內居中,使用指定的 fillbyte 填充兩邊的空位(默認使用 ASCII 空格符)。 對于
bytes
對象,如果 width 小于等于len(s)
則返回原序列的副本。備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.ljust(width[, fillbyte])?
- bytearray.ljust(width[, fillbyte])?
返回原對象的副本,在長(cháng)度為 width 的序列中靠左對齊。 使用指定的 fillbyte 填充空位(默認使用 ASCII 空格符)。 對于
bytes
對象,如果 width 小于等于len(s)
則返回原序列的副本。備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.lstrip([chars])?
- bytearray.lstrip([chars])?
返回原序列的副本,移除指定的前導字節。 chars 參數為指定要移除字節值集合的二進(jìn)制序列 —— 這個(gè)名稱(chēng)表明此方法通常是用于 ASCII 字符。 如果省略或為
None
,則 chars 參數默認移除 ASCII 空白符。 chars 參數并非指定單個(gè)前綴;而是會(huì )移除參數值的所有組合:>>> b' spacious '.lstrip() b'spacious ' >>> b'www.example.com'.lstrip(b'cmowz.') b'example.com'
要移除的二進(jìn)制序列可以是任意 bytes-like object 。 要刪除單個(gè)前綴字符串,而不是全部給定集合中的字符,請參見(jiàn)
str.removeprefix()
方法。 例如:>>> b'Arthur: three!'.lstrip(b'Arthur: ') b'ee!' >>> b'Arthur: three!'.removeprefix(b'Arthur: ') b'three!'
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.rjust(width[, fillbyte])?
- bytearray.rjust(width[, fillbyte])?
返回原對象的副本,在長(cháng)度為 width 的序列中靠右對齊。 使用指定的 fillbyte 填充空位(默認使用 ASCII 空格符)。 對于
bytes
對象,如果 width 小于等于len(s)
則返回原序列的副本。備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.rsplit(sep=None, maxsplit=- 1)?
- bytearray.rsplit(sep=None, maxsplit=- 1)?
將二進(jìn)制序列拆分為相同類(lèi)型的子序列,使用 sep 作為分隔符。 如果給出了 maxsplit,則最多進(jìn)行 maxsplit 次拆分,從 最右邊 開(kāi)始。 如果 sep 未指定或為
None
,任何只包含 ASCII 空白符的子序列都會(huì )被作為分隔符。 除了從右邊開(kāi)始拆分,rsplit()
的其他行為都類(lèi)似于下文所述的split()
。
- bytes.rstrip([chars])?
- bytearray.rstrip([chars])?
返回原序列的副本,移除指定的末尾字節。 chars 參數為指定要移除字節值集合的二進(jìn)制序列 —— 這個(gè)名稱(chēng)表明此方法通常是用于 ASCII 字符。 如果省略或為
None
,則 chars 參數默認移除 ASCII 空白符。 chars 參數并非指定單個(gè)后綴;而是會(huì )移除參數值的所有組合:>>> b' spacious '.rstrip() b' spacious' >>> b'mississippi'.rstrip(b'ipz') b'mississ'
要移除的二進(jìn)制序列可以是任意 bytes-like object 。 要刪除單個(gè)后綴字符串,而不是全部給定集合中的字符,請參見(jiàn)
str.removesuffix()
方法。 例如:>>> b'Monty Python'.rstrip(b' Python') b'M' >>> b'Monty Python'.removesuffix(b' Python') b'Monty'
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.split(sep=None, maxsplit=- 1)?
- bytearray.split(sep=None, maxsplit=- 1)?
將二進(jìn)制序列拆分為相同類(lèi)型的子序列,使用 sep 作為分隔符。 如果給出了 maxsplit 且非負值,則最多進(jìn)行 maxsplit 次拆分(因此,列表最多會(huì )有
maxsplit+1
個(gè)元素)。 如果 maxsplit 未指定或為-1
,則不限制拆分次數(進(jìn)行所有可能的拆分)。如果給出了 sep,則連續的分隔符不會(huì )被組合在一起而是被視為分隔空子序列 (例如
b'1,,2'.split(b',')
將返回[b'1', b'', b'2']
)。 sep 參數可能為一個(gè)多字節序列 (例如b'1<>2<>3'.split(b'<>')
將返回[b'1', b'2', b'3']
)。 使用指定的分隔符拆分空序列將返回[b'']
或[bytearray(b'')]
,具體取決于被拆分對象的類(lèi)型。 sep 參數可以是任意 bytes-like object。例如:
>>> 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'']
如果 sep 未指定或為
None
,則會(huì )應用另一種拆分算法:連續的 ASCII 空白符會(huì )被視為單個(gè)分隔符,其結果將不包含序列開(kāi)頭或末尾的空白符。 因此,在不指定分隔符的情況下對空序列或僅包含 ASCII 空白符的序列進(jìn)行拆分將返回[]
。例如:
>>> 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([chars])?
- bytearray.strip([chars])?
返回原序列的副本,移除指定的開(kāi)頭和末尾字節。 chars 參數為指定要移除字節值集合的二進(jìn)制序列 —— 這個(gè)名稱(chēng)表明此方法通常是用于 ASCII 字符。 如果省略或為
None
,則 chars 參數默認移除 ASCII 空白符。 chars 參數并非指定單個(gè)前綴或后綴;而是會(huì )移除參數值的所有組合:>>> b' spacious '.strip() b'spacious' >>> b'www.example.com'.strip(b'cmowz.') b'example'
要移除的字節值二進(jìn)制序列可以是任意 bytes-like object。
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
以下 bytes 和 bytearray 對象的方法會(huì )假定使用兼容 ASCII 的二進(jìn)制格式,不應當被應用于任意二進(jìn)制數據。 請注意本小節中所有的 bytearray 方法都 不是 原地執行操作,而是會(huì )產(chǎn)生新的對象。
- bytes.capitalize()?
- bytearray.capitalize()?
返回原序列的副本,其中每個(gè)字節將都將被解讀為一個(gè) ASCII 字符,并且第一個(gè)字節的字符大寫(xiě)而其余的小寫(xiě)。 非 ASCII 字節值將保持原樣不變。
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.expandtabs(tabsize=8)?
- bytearray.expandtabs(tabsize=8)?
返回序列的副本,其中所有的 ASCII 制表符會(huì )由一個(gè)或多個(gè) ASCII 空格替換,具體取決于當前列位置和給定的制表符寬度。 每 tabsize 個(gè)字節設為一個(gè)制表位(默認值 8 時(shí)設定的制表位在列 0, 8, 16 依次類(lèi)推)。 要展開(kāi)序列,當前列位置將被設為零并逐一檢查序列中的每個(gè)字節。 如果字節為 ASCII 制表符 (
b'\t'
),則并在結果中插入一個(gè)或多個(gè)空格符,直到當前列等于下一個(gè)制表位。 (制表符本身不會(huì )被復制。) 如果當前字節為 ASCII 換行符 (b'\n'
) 或回車(chē)符 (b'\r'
),它會(huì )被復制并將當前列重設為零。 任何其他字節會(huì )被不加修改地復制并將當前列加一,不論該字節值在被打印時(shí)會(huì )如何顯示:>>> b'01\t012\t0123\t01234'.expandtabs() b'01 012 0123 01234' >>> b'01\t012\t0123\t01234'.expandtabs(4) b'01 012 0123 01234'
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.isalnum()?
- bytearray.isalnum()?
如果序列中所有字節都是字母類(lèi) ASCII 字符或 ASCII 十進(jìn)制數碼并且序列非空則返回
True
,否則返回False
。 字母類(lèi) ASCII 字符就是字節值包含在序列b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
中的字符。 ASCII 十進(jìn)制數碼就是字節值包含在序列b'0123456789'
中的字符。例如:
>>> b'ABCabc1'.isalnum() True >>> b'ABC abc1'.isalnum() False
- bytes.isalpha()?
- bytearray.isalpha()?
如果序列中所有字節都是字母類(lèi) ASCII 字符并且序列不非空則返回
True
,否則返回False
。 字母類(lèi) 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 十進(jìn)制數碼并且序列非空則返回
True
,否則返回False
。 ASCII 十進(jìn)制數碼就是字節值包含在序列b'0123456789'
中的字符。例如:
>>> b'1234'.isdigit() True >>> b'1.23'.isdigit() False
- bytes.islower()?
- bytearray.islower()?
如果序列中至少有一個(gè)小寫(xiě)的 ASCII 字符并且沒(méi)有大寫(xiě)的 ASCII 字符則返回
True
,否則返回False
。例如:
>>> b'hello world'.islower() True >>> b'Hello world'.islower() False
小寫(xiě) ASCII 字符就是字節值包含在序列
b'abcdefghijklmnopqrstuvwxyz'
中的字符。 大寫(xiě) ASCII 字符就是字節值包含在序列b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
中的字符。
- bytes.isspace()?
- bytearray.isspace()?
如果序列中所有字節都是 ASCII 空白符并且序列非空則返回
True
,否則返回False
。 ASCII 空白符就是字節值包含在序列b' \t\n\r\x0b\f'
(空格, 制表, 換行, 回車(chē), 垂直制表, 進(jìn)紙) 中的字符。
- bytes.istitle()?
- bytearray.istitle()?
如果序列為 ASCII 標題大小寫(xiě)形式并且序列非空則返回
True
,否則返回False
。 請參閱bytes.title()
了解有關(guān)“標題大小寫(xiě)”的詳細定義。例如:
>>> b'Hello World'.istitle() True >>> b'Hello world'.istitle() False
- bytes.isupper()?
- bytearray.isupper()?
如果序列中至少有一個(gè)大寫(xiě)字母 ASCII 字符并且沒(méi)有小寫(xiě) ASCII 字符則返回
True
,否則返回False
。例如:
>>> b'HELLO WORLD'.isupper() True >>> b'Hello world'.isupper() False
小寫(xiě) ASCII 字符就是字節值包含在序列
b'abcdefghijklmnopqrstuvwxyz'
中的字符。 大寫(xiě) ASCII 字符就是字節值包含在序列b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
中的字符。
- bytes.lower()?
- bytearray.lower()?
返回原序列的副本,其所有大寫(xiě) ASCII 字符均轉換為對應的小寫(xiě)形式。
例如:
>>> b'Hello World'.lower() b'hello world'
小寫(xiě) ASCII 字符就是字節值包含在序列
b'abcdefghijklmnopqrstuvwxyz'
中的字符。 大寫(xiě) ASCII 字符就是字節值包含在序列b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
中的字符。備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.splitlines(keepends=False)?
- bytearray.splitlines(keepends=False)?
返回由原二進(jìn)制序列中各行組成的列表,在 ASCII 行邊界符的位置拆分。 此方法使用 universal newlines 方式來(lái)分行。 結果列表中不包含換行符,除非給出了 keepends 且為真值。
例如:
>>> 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']
不同于
split()
,當給出了分隔符 sep 時(shí),對于空字符串此方法將返回一個(gè)空列表,而末尾的換行不會(huì )令結果中增加額外的行:>>> 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()?
返回原序列的副本,其所有小寫(xiě) ASCII 字符均轉換為對應的大寫(xiě)形式,反之亦反。
例如:
>>> b'Hello World'.swapcase() b'hELLO wORLD'
小寫(xiě) ASCII 字符就是字節值包含在序列
b'abcdefghijklmnopqrstuvwxyz'
中的字符。 大寫(xiě) ASCII 字符就是字節值包含在序列b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
中的字符。不同于
str.swapcase()
,在些二進(jìn)制版本下bin.swapcase().swapcase() == bin
總是成立。 大小寫(xiě)轉換在 ASCII 中是對稱(chēng)的,即使其對于任意 Unicode 碼位來(lái)說(shuō)并不總是成立。備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.title()?
- bytearray.title()?
返回原二進(jìn)制序列的標題版本,其中每個(gè)單詞以一個(gè)大寫(xiě) ASCII 字符為開(kāi)頭,其余字母為小寫(xiě)。 不區別大小寫(xiě)的字節值將保持原樣不變。
例如:
>>> b'Hello world'.title() b'Hello World'
小寫(xiě) ASCII 字符就是字節值包含在序列
b'abcdefghijklmnopqrstuvwxyz'
中的字符。 大寫(xiě) ASCII 字符就是字節值包含在序列b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
中的字符。 所有其他字節值都不區分大小寫(xiě)。該算法使用一種簡(jiǎn)單的與語(yǔ)言無(wú)關(guān)的定義,將連續的字母組合視為單詞。 該定義在多數情況下都很有效,但它也意味著(zhù)代表縮寫(xiě)形式與所有格的撇號也會(huì )成為單詞邊界,這可能導致不希望的結果:
>>> b"they're bill's friends from the UK".title() b"They'Re Bill'S Friends From The Uk"
可以使用正則表達式來(lái)構建針對撇號的特別處理:
>>> 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 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.upper()?
- bytearray.upper()?
返回原序列的副本,其所有小寫(xiě) ASCII 字符均轉換為對應的大寫(xiě)形式。
例如:
>>> b'Hello World'.upper() b'HELLO WORLD'
小寫(xiě) ASCII 字符就是字節值包含在序列
b'abcdefghijklmnopqrstuvwxyz'
中的字符。 大寫(xiě) ASCII 字符就是字節值包含在序列b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
中的字符。備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
- bytes.zfill(width)?
- bytearray.zfill(width)?
返回原序列的副本,在左邊填充
b'0'
數碼使序列長(cháng)度為 width。 正負值前綴 (b'+'
/b'-'
) 的處理方式是在正負符號 之后 填充而非在之前。 對于bytes
對象,如果 width 小于等于len(seq)
則返回原序列。例如:
>>> b"42".zfill(5) b'00042' >>> b"-42".zfill(5) b'-0042'
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
printf
風(fēng)格的字節串格式化?
備注
此處介紹的格式化操作具有多種怪異特性,可能導致許多常見(jiàn)錯誤(例如無(wú)法正確顯示元組和字典)。 如果要打印的值可能為元組或字典,請將其放入一個(gè)元組中。
字節串對象 (bytes
/bytearray
) 具有一種特殊的內置操作:使用 %
(取模) 運算符。 這也被稱(chēng)為字節串的 格式化 或 插值 運算符。 對于 format % values
(其中 format 為一個(gè)字節串對象),在 format 中的 %
轉換標記符將被替換為零個(gè)或多個(gè) values 條目。 其效果類(lèi)似于在 C 語(yǔ)言中使用 sprintf()
。
如果 format 要求一個(gè)單獨參數,則 values 可以為一個(gè)非元組對象。 5 否則的話(huà),values 必須或是是一個(gè)包含項數與格式字節串對象中指定的轉換符項數相同的元組,或者是一個(gè)單獨的映射對象(例如元組)。
轉換標記符包含兩個(gè)或更多字符并具有以下組成,且必須遵循此處規定的順序:
'%'
字符,用于標記轉換符的起始。映射鍵(可選),由加圓括號的字符序列組成 (例如
(somename)
)。轉換旗標(可選),用于影響某些轉換類(lèi)型的結果。
最小字段寬度(可選)。 如果指定為
'*'
(星號),則實(shí)際寬度會(huì )從 values 元組的下一元素中讀取,要轉換的對象則為最小字段寬度和可選的精度之后的元素。精度(可選),以在
'.'
(點(diǎn)號) 之后加精度值的形式給出。 如果指定為'*'
(星號),則實(shí)際精度會(huì )從 values 元組的下一元素中讀取,要轉換的對象則為精度之后的元素。長(cháng)度修飾符(可選)。
轉換類(lèi)型。
當右邊的參數為一個(gè)字典(或其他映射類(lèi)型)時(shí),字節串對象中的格式 必須 包含加圓括號的映射鍵,對應 '%'
字符之后字典中的每一項。 映射鍵將從映射中選取要格式化的值。 例如:
>>> print(b'%(language)s has %(number)03d quote types.' %
... {b'language': b"Python", b"number": 2})
b'Python has 002 quote types.'
在此情況下格式中不能出現 *
標記符(因其需要一個(gè)序列類(lèi)的參數列表)。
轉換旗標為:
旗標 |
含意 |
---|---|
|
值的轉換將使用“替代形式”(具體定義見(jiàn)下文)。 |
|
轉換將為數字值填充零字符。 |
|
轉換值將靠左對齊(如果同時(shí)給出 |
|
(空格) 符號位轉換產(chǎn)生的正數(或空字符串)前將留出一個(gè)空格。 |
|
符號字符 ( |
可以給出長(cháng)度修飾符 (h
, l
或 L
),但會(huì )被忽略,因為對 Python 來(lái)說(shuō)沒(méi)有必要 -- 所以 %ld
等價(jià)于 %d
。
轉換類(lèi)型為:
轉換符 |
含意 |
備注 |
---|---|---|
|
有符號十進(jìn)制整數。 |
|
|
有符號十進(jìn)制整數。 |
|
|
有符號八進(jìn)制數。 |
(1) |
|
過(guò)時(shí)類(lèi)型 -- 等價(jià)于 |
(8) |
|
有符號十六進(jìn)制數(小寫(xiě))。 |
(2) |
|
有符號十六進(jìn)制數(大寫(xiě))。 |
(2) |
|
浮點(diǎn)指數格式(小寫(xiě))。 |
(3) |
|
浮點(diǎn)指數格式(大寫(xiě))。 |
(3) |
|
浮點(diǎn)十進(jìn)制格式。 |
(3) |
|
浮點(diǎn)十進(jìn)制格式。 |
(3) |
|
浮點(diǎn)格式。 如果指數小于 -4 或不小于精度則使用小寫(xiě)指數格式,否則使用十進(jìn)制格式。 |
(4) |
|
浮點(diǎn)格式。 如果指數小于 -4 或不小于精度則使用大寫(xiě)指數格式,否則使用十進(jìn)制格式。 |
(4) |
|
單個(gè)字節(接受整數或單個(gè)字節對象)。 |
|
|
字節串(任何遵循 緩沖區協(xié)議 或是具有 |
(5) |
|
|
(6) |
|
Bytes (converts any Python object using
|
(5) |
|
|
(7) |
|
不轉換參數,在結果中輸出一個(gè) |
注釋?zhuān)?/p>
此替代形式會(huì )在第一個(gè)數碼之前插入標示八進(jìn)制數的前綴 (
'0o'
)。此替代形式會(huì )在第一個(gè)數碼之前插入
'0x'
或'0X'
前綴(取決于是使用'x'
還是'X'
格式)。此替代形式總是會(huì )在結果中包含一個(gè)小數點(diǎn),即使其后并沒(méi)有數碼。
小數點(diǎn)后的數碼位數由精度決定,默認為 6。
此替代形式總是會(huì )在結果中包含一個(gè)小數點(diǎn),末尾各位的零不會(huì )如其他情況下那樣被移除。
小數點(diǎn)前后的有效數碼位數由精度決定,默認為 6。
如果精度為
N
,輸出將截短為N
個(gè)字符。b'%s'
已棄用,但在 3.x 系列中將不會(huì )被移除。b'%r'
已棄用,但在 3.x 系列中將不會(huì )被移除。參見(jiàn) PEP 237。
備注
此方法的 bytearray 版本 并非 原地操作 —— 它總是產(chǎn)生一個(gè)新對象,即便沒(méi)有做任何改變。
參見(jiàn)
PEP 461 - 為 bytes 和 bytearray 添加 % 格式化
3.5 新版功能.
內存視圖?
memoryview
對象允許 Python 代碼訪(fǎng)問(wèn)一個(gè)對象的內部數據,只要該對象支持 緩沖區協(xié)議 而無(wú)需進(jìn)行拷貝。
- class memoryview(object)?
創(chuàng )建一個(gè)引用 object 的
memoryview
。 object 必須支持緩沖區協(xié)議。支持緩沖區協(xié)議的內置對象有bytes
和bytearray
。memoryview
有 元素 的概念, 元素 指由原始 object 處理的原子內存單元。對于許多簡(jiǎn)單的類(lèi)型,如bytes
和bytearray
,一個(gè)元素是一個(gè)字節,但其他類(lèi)型,如array.array
可能有更大的元素。len(view)
與tolist
的長(cháng)度相等。 如果view.ndim = 0
,則其長(cháng)度為 1。 如果view.ndim = 1
,則其長(cháng)度等于 view 中元素的數量。 對于更高的維度,其長(cháng)度等于表示 view 的嵌套列表的長(cháng)度。itemsize
屬性可向你給出單個(gè)元素所占的字節數。memoryview
支持通過(guò)切片和索引訪(fǎng)問(wèn)其元素。 一維切片的結果將是一個(gè)子視圖:>>> v = memoryview(b'abcefg') >>> v[1] 98 >>> v[-1] 103 >>> v[1:4] <memory at 0x7f3ddc9f4350> >>> bytes(v[1:4]) b'bce'
如果
format
是一個(gè)來(lái)自于struct
模塊的原生格式說(shuō)明符,則也支持使用整數或由整數構成的元組進(jìn)行索引,并返回具有正確類(lèi)型的單個(gè) 元素。 一維內存視圖可以使用一個(gè)整數或由一個(gè)整數構成的元組進(jìn)行索引。 多維內存視圖可以使用由恰好 ndim 個(gè)整數構成的元素進(jìn)行索引,ndim 即其維度。 零維內存視圖可以使用空元組進(jìn)行索引。這里是一個(gè)使用非字節格式的例子:
>>> import array >>> a = array.array('l', [-11111111, 22222222, -33333333, 44444444]) >>> m = memoryview(a) >>> m[0] -11111111 >>> m[-1] 44444444 >>> m[::2].tolist() [-11111111, -33333333]
如果下層對象是可寫(xiě)的,則內存視圖支持一維切片賦值。 改變大小則不被允許:
>>> 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' 的可哈希(只讀)類(lèi)型構成的一維內存視圖同樣是可哈希的。 哈希定義為
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 版更改: 一維內存視圖現在可以被切片。 帶有格式符號 'B', 'b' 或 'c' 的一維內存視圖現在是可哈希的。
在 3.4 版更改: 內存視圖現在會(huì )自動(dòng)注冊為
collections.abc.Sequence
在 3.5 版更改: 內存視圖現在可使用整數元組進(jìn)行索引。
memoryview
具有以下一些方法:- __eq__(exporter)?
memoryview 與 PEP 3118 中的導出器這兩者如果形狀相同,并且如果當使用
struct
語(yǔ)法解讀操作數的相應格式代碼時(shí)所有對應值都相同,則它們就是等價(jià)的。對于
tolist()
當前所支持的struct
格式字符串子集,如果v.tolist() == w.tolist()
則v
和w
相等:>>> 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
請注意,與浮點(diǎn)數的情況一樣,對于內存視圖對象來(lái)說(shuō),
v is w
也 并不 意味著(zhù)v == w
。在 3.3 版更改: 之前的版本比較原始內存時(shí)會(huì )忽略條目的格式與邏輯數組結構。
- tobytes(order='C')?
將緩沖區中的數據作為字節串返回。 這相當于在內存視圖上調用
bytes
構造器。>>> m = memoryview(b"abc") >>> m.tobytes() b'abc' >>> bytes(m) b'abc'
對于非連續數組,結果等于平面化表示的列表,其中所有元素都轉換為字節串。
tobytes()
支持所有格式字符串,不符合struct
模塊語(yǔ)法的那些也包括在內。3.8 新版功能: order 可以為 {'C', 'F', 'A'}。 當 order 為 'C' 或 'F' 時(shí),原始數組的數據會(huì )被轉換至 C 或 Fortran 順序。 對于連續視圖,'A' 會(huì )返回物理內存的精確副本。 特別地,內存中的 Fortran 順序會(huì )被保留。對于非連續視圖,數據會(huì )先被轉換為 C 形式。 order=None 與 order='C' 是相同的。
- hex([sep[, bytes_per_sep]])?
返回一個(gè)字符串對象,其中分別以?xún)蓚€(gè)十六進(jìn)制數碼表示緩沖區里的每個(gè)字節。
>>> m = memoryview(b"abc") >>> m.hex() '616263'
3.5 新版功能.
在 3.8 版更改: 與
bytes.hex()
相似,memoryview.hex()
現在支持可選的 sep 和 bytes_per_sep 參數以在十六進(jìn)制輸出的字節之間插入分隔符。
- tolist()?
將緩沖區內的數據以一個(gè)元素列表的形式返回。
>>> 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]
- toreadonly()?
返回 memoryview 對象的只讀版本。 原始的 memoryview 對象不會(huì )被改變。
>>> m = memoryview(bytearray(b'abc')) >>> mm = m.toreadonly() >>> mm.tolist() [89, 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()?
釋放由內存視圖對象所公開(kāi)的底層緩沖區。 許多對象在被視圖所獲取時(shí)都會(huì )采取特殊動(dòng)作(例如,
bytearray
將會(huì )暫時(shí)禁止調整大?。?;因此,調用 release() 可以方便地盡早去除這些限制(并釋放任何多余的資源)。在此方法被調用后,任何對視圖的進(jìn)一步操作將引發(fā)
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
語(yǔ)句,可以通過(guò)上下文管理協(xié)議達到類(lèi)似的效果:>>> 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[, shape])?
將內存視圖轉化為新的格式或形狀。 shape 默認為
[byte_length//new_itemsize]
,這意味著(zhù)結果視圖將是一維的。 返回值是一個(gè)新的內存視圖,但緩沖區本身不會(huì )被復制。 支持的轉化有 1D -> C-contiguous 和 C-contiguous -> 1D。目標格式僅限于
struct
語(yǔ)法中的單一元素原生格式。 其中一種格式必須為字節格式 ('B', 'b' 或 'c')。 結果的字節長(cháng)度必須與原始長(cháng)度相同。將 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): File "<stdin>", line 1, in <module> ValueError: memoryview: invalid value 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 版更改: 當轉換為字節視圖時(shí),源格式將不再受限。
還存在一些可用的只讀屬性:
- obj?
內存視圖的下層對象:
>>> b = bytearray(b'xyz') >>> m = memoryview(b) >>> m.obj is b True
3.3 新版功能.
- nbytes?
nbytes == product(shape) * itemsize == len(m.tobytes())
。 這是數組在連續表示時(shí)將會(huì )占用的空間總字節數。 它不一定等于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?
一個(gè)表明內存是否只讀的布爾值。
- format?
一個(gè)字符串,包含視圖中每個(gè)元素的格式(表示為
struct
模塊樣式)。 內存視圖可以從具有任意格式字符串的導出器創(chuàng )建,但某些方法 (例如tolist()
) 僅限于原生的單元素格式。在 3.3 版更改: 格式
'B'
現在會(huì )按照 struct 模塊語(yǔ)法來(lái)處理。 這意味著(zhù)memoryview(b'abc')[0] == b'abc'[0] == 97
。
- itemsize?
memoryview 中每個(gè)元素以字節表示的大小:
>>> import array, struct >>> m = memoryview(array.array('H', [32000, 32001, 32002])) >>> m.itemsize 2 >>> m[0] 32000 >>> struct.calcsize('H') == m.itemsize True
- ndim?
一個(gè)整數,表示內存所代表的多維數組具有多少個(gè)維度。
- shape?
一個(gè)整數元組,通過(guò)
ndim
的長(cháng)度值給出內存所代表的 N 維數組的形狀。在 3.3 版更改: 當 ndim = 0 時(shí)值為空元組而不再為
None
。
- strides?
一個(gè)整數元組,通過(guò)
ndim
的長(cháng)度給出以字節表示的大小,以便訪(fǎng)問(wèn)數組中每個(gè)維度上的每個(gè)元素。在 3.3 版更改: 當 ndim = 0 時(shí)值為空元組而不再為
None
。
- suboffsets?
供 PIL 風(fēng)格的數組內部使用。 該值僅作為參考信息。
- c_contiguous?
一個(gè)表明內存是否為 C-contiguous 的布爾值。
3.3 新版功能.
- f_contiguous?
一個(gè)表明內存是否為 Fortran contiguous 的布爾值。
3.3 新版功能.
- contiguous?
一個(gè)表明內存是否為 contiguous 的布爾值。
3.3 新版功能.
集合類(lèi)型 --- set
, frozenset
?
set 對象是由具有唯一性的 hashable 對象所組成的無(wú)序多項集。 常見(jiàn)的用途包括成員檢測、從序列中去除重復項以及數學(xué)中的集合類(lèi)計算,例如交集、并集、差集與對稱(chēng)差集等等。 (關(guān)于其他容器對象請參看 dict
, list
與 tuple
等內置類(lèi),以及 collections
模塊。)
與其他多項集一樣,集合也支持 x in set
, len(set)
和 for x in set
。 作為一種無(wú)序的多項集,集合并不記錄元素位置或插入順序。 相應地,集合不支持索引、切片或其他序列類(lèi)的操作。
目前有兩種內置集合類(lèi)型,set
和 frozenset
。 set
類(lèi)型是可變的 --- 其內容可以使用 add()
和 remove()
這樣的方法來(lái)改變。 由于是可變類(lèi)型,它沒(méi)有哈希值,且不能被用作字典的鍵或其他集合的元素。 frozenset
類(lèi)型是不可變并且為 hashable --- 其內容在被創(chuàng )建后不能再改變;因此它可以被用作字典的鍵或其他集合的元素。
除了可以使用 set
構造器,非空的 set (不是 frozenset) 還可以通過(guò)將以逗號分隔的元素列表包含于花括號之內來(lái)創(chuàng )建,例如: {'jack', 'sjoerd'}
。
兩個(gè)類(lèi)的構造器具有相同的作用方式:
- class set([iterable])?
- class frozenset([iterable])?
返回一個(gè)新的 set 或 frozenset 對象,其元素來(lái)自于 iterable。 集合的元素必須為 hashable。 要表示由集合對象構成的集合,所有的內層集合必須為
frozenset
對象。 如果未指定 iterable,則將返回一個(gè)新的空集合。集合可用多種方式來(lái)創(chuàng )建:
使用花括號內以逗號分隔元素的方式:
{'jack', 'sjoerd'}
使用集合推導式:
{c for c in 'abracadabra' if c not in 'abc'}
使用類(lèi)型構造器:
set()
,set('foobar')
,set(['a', 'b', 'foo'])
set
和frozenset
的實(shí)例提供以下操作:- len(s)
返回集合 s 中的元素數量(即 s 的基數)。
- x in s
檢測 x 是否為 s 中的成員。
- x not in s
檢測 x 是否非 s 中的成員。
- isdisjoint(other)?
如果集合中沒(méi)有與 other 共有的元素則返回
True
。 當且僅當兩個(gè)集合的交集為空集合時(shí),兩者為不相交集合。
- issubset(other)?
- set <= other
檢測是否集合中的每個(gè)元素都在 other 之中。
- set < other
檢測集合是否為 other 的真子集,即
set <= other and set != other
。
- issuperset(other)?
- set >= other
檢測是否 other 中的每個(gè)元素都在集合之中。
- set > other
檢測集合是否為 other 的真超集,即
set >= other and set != other
。
- union(*others)?
- set | other | ...
返回一個(gè)新集合,其中包含來(lái)自原集合以及 others 指定的所有集合中的元素。
- intersection(*others)?
- set & other & ...
返回一個(gè)新集合,其中包含原集合以及 others 指定的所有集合中共有的元素。
- difference(*others)?
- set - other - ...
返回一個(gè)新集合,其中包含原集合中在 others 指定的其他集合中不存在的元素。
- symmetric_difference(other)?
- set ^ other
返回一個(gè)新集合,其中的元素或屬于原集合或屬于 other 指定的其他集合,但不能同時(shí)屬于兩者。
- copy()?
返回原集合的淺拷貝。
注意,
union()
、intersection()
、difference()
、symmetric_difference()
、issubset()
和issuperset()
方法的非運算符版本可以接受任何可迭代對象作為一個(gè)參數。相比之下,基于運算符的對應方法則要求參數為集合對象。這就避開(kāi)了像set('abc') & 'cbs'
這樣容易出錯的結構,而換成了可讀性更好的set('abc').intersection('cbs')
。set
和frozenset
均支持集合與集合的比較。 兩個(gè)集合當且僅當每個(gè)集合中的每個(gè)元素均包含于另一個(gè)集合之內(即各為對方的子集)時(shí)則相等。 一個(gè)集合當且僅當其為另一個(gè)集合的真子集(即為后者的子集但兩者不相等)時(shí)則小于另一個(gè)集合。 一個(gè)集合當且僅當其為另一個(gè)集合的真超集(即為后者的超集但兩者不相等)時(shí)則大于另一個(gè)集合。set
的實(shí)例與frozenset
的實(shí)例之間基于它們的成員進(jìn)行比較。 例如set('abc') == frozenset('abc')
返回True
,set('abc') in set([frozenset('abc')])
也一樣。子集與相等比較并不能推廣為完全排序函數。 例如,任意兩個(gè)非空且不相交的集合不相等且互不為對方的子集,因此以下 所有 比較均返回
False
:a<b
,a==b
, ora>b
。由于集合僅定義了部分排序(子集關(guān)系),因此由集合構成的列表
list.sort()
方法的輸出并無(wú)定義。集合的元素,與字典的鍵類(lèi)似,必須為 hashable。
混合了
set
實(shí)例與frozenset
的二進(jìn)制位運算將返回與第一個(gè)操作數相同的類(lèi)型。例如:frozenset('ab') | set('bc')
將返回frozenset
的實(shí)例。下表列出了可用于
set
而不能用于不可變的frozenset
實(shí)例的操作:- update(*others)?
- set |= other | ...
更新集合,添加來(lái)自 others 中的所有元素。
- intersection_update(*others)?
- set &= other & ...
更新集合,只保留其中在所有 others 中也存在的元素。
- difference_update(*others)?
- set -= other | ...
更新集合,移除其中也存在于 others 中的元素。
- symmetric_difference_update(other)?
- set ^= other
更新集合,只保留存在于集合的一方而非共同存在的元素。
- add(elem)?
將元素 elem 添加到集合中。
- discard(elem)?
如果元素 elem 存在于集合中則將其移除。
- clear()?
從集合中移除所有元素。
請注意,非運算符版本的
update()
,intersection_update()
,difference_update()
和symmetric_difference_update()
方法將接受任意可迭代對象作為參數。請注意,
__contains__()
,remove()
和discard()
方法的 elem 參數可能是一個(gè) set。 為支持對一個(gè)等價(jià)的 frozenset 進(jìn)行搜索,會(huì )根據 elem 臨時(shí)創(chuàng )建一個(gè)該類(lèi)型對象。
映射類(lèi)型 --- dict
?
mapping 對象會(huì )將 hashable 值映射到任意對象。 映射屬于可變對象。 目前僅有一種標準映射類(lèi)型 字典。 (關(guān)于其他容器對象請參看 list
, set
與 tuple
等內置類(lèi),以及 collections
模塊。)
字典的鍵 幾乎 可以是任何值。 非 hashable 的值,即包含列表、字典或其他可變類(lèi)型的值(此類(lèi)對象基于值而非對象標識進(jìn)行比較)不可用作鍵。 數字類(lèi)型用作鍵時(shí)遵循數字比較的一般規則:如果兩個(gè)數值相等 (例如 1
和 1.0
) 則兩者可以被用來(lái)索引同一字典條目。 (但是請注意,由于計算機對于浮點(diǎn)數存儲的只是近似值,因此將其用作字典鍵是不明智的。)
- class dict(**kwargs)?
- class dict(mapping, **kwargs)
- class dict(iterable, **kwargs)
返回一個(gè)新的字典,基于可選的位置參數和可能為空的關(guān)鍵字參數集來(lái)初始化。
字典可用多種方式來(lái)創(chuàng )建:
使用花括號內以逗號分隔
鍵: 值
對的方式:{'jack': 4098, 'sjoerd': 4127}
or{4098: 'jack', 4127: 'sjoerd'}
使用字典推導式:
{}
,{x: x ** 2 for x in range(10)}
使用類(lèi)型構造器:
dict()
,dict([('foo', 100), ('bar', 200)])
,dict(foo=100, bar=200)
如果沒(méi)有給出位置參數,將創(chuàng )建一個(gè)空字典。 如果給出一個(gè)位置參數并且其屬于映射對象,將創(chuàng )建一個(gè)具有與映射對象相同鍵值對的字典。 否則的話(huà),位置參數必須為一個(gè) iterable 對象。 該可迭代對象中的每一項本身必須為一個(gè)剛好包含兩個(gè)元素的可迭代對象。 每一項中的第一個(gè)對象將成為新字典的一個(gè)鍵,第二個(gè)對象將成為其對應的值。 如果一個(gè)鍵出現一次以上,該鍵的最后一個(gè)值將成為其在新字典中對應的值。
如果給出了關(guān)鍵字參數,則關(guān)鍵字參數及其值會(huì )被加入到基于位置參數創(chuàng )建的字典。 如果要加入的鍵已存在,來(lái)自關(guān)鍵字參數的值將替代來(lái)自位置參數的值。
作為演示,以下示例返回的字典均等于
{"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
像第一個(gè)例子那樣提供關(guān)鍵字參數的方式只能使用有效的 Python 標識符作為鍵。 其他方式則可使用任何有效的鍵。
這些是字典所支持的操作(因而自定義的映射類(lèi)型也應當支持):
- list(d)
返回字典 d 中使用的所有鍵的列表。
- len(d)
返回字典 d 中的項數。
- d[key]
返回 d 中以 key 為鍵的項。 如果映射中不存在 key 則會(huì )引發(fā)
KeyError
。如果字典的子類(lèi)定義了方法
__missing__()
并且 key 不存在,則d[key]
操作將調用該方法并附帶鍵 key 作為參數。d[key]
隨后將返回或引發(fā)__missing__(key)
調用所返回或引發(fā)的任何對象或異常。 沒(méi)有其他操作或方法會(huì )發(fā)起調用__missing__()
。 如果未定義__missing__()
,則會(huì )引發(fā)KeyError
。__missing__()
必須是一個(gè)方法;它不能是一個(gè)實(shí)例變量:>>> class Counter(dict): ... def __missing__(self, key): ... return 0 >>> c = Counter() >>> c['red'] 0 >>> c['red'] += 1 >>> c['red'] 1
上面的例子顯示了
collections.Counter
實(shí)現的部分代碼。 還有另一個(gè)不同的__missing__
方法是由collections.defaultdict
所使用的。
- d[key] = value
將
d[key]
設為 value。
- del d[key]
將
d[key]
從 d 中移除。 如果映射中不存在 key 則會(huì )引發(fā)KeyError
。
- key in d
如果 d 中存在鍵 key 則返回
True
,否則返回False
。
- key not in d
等價(jià)于
not key in d
。
- iter(d)
返回以字典的鍵為元素的迭代器。 這是
iter(d.keys())
的快捷方式。
- clear()?
移除字典中的所有元素。
- copy()?
返回原字典的淺拷貝。
- classmethod fromkeys(iterable[, value])?
使用來(lái)自 iterable 的鍵創(chuàng )建一個(gè)新字典,并將鍵值設為 value。
fromkeys()
是一個(gè)返回新字典的類(lèi)方法。 value 默認為None
。 所有值都只引用一個(gè)單獨的實(shí)例,因此讓 value 成為一個(gè)可變對象例如空列表通常是沒(méi)有意義的。 要獲取不同的值,請改用 字典推導式。
- get(key[, default])?
如果 key 存在于字典中則返回 key 的值,否則返回 default。 如果 default 未給出則默認為
None
,因而此方法絕不會(huì )引發(fā)KeyError
。
- pop(key[, default])?
如果 key 存在于字典中則將其移除并返回其值,否則返回 default。 如果 default 未給出且 key 不存在于字典中,則會(huì )引發(fā)
KeyError
。
- popitem()?
從字典中移除并返回一個(gè)
(鍵, 值)
對。 鍵值對會(huì )按 LIFO 的順序被返回。popitem()
適用于對字典進(jìn)行消耗性的迭代,這在集合算法中經(jīng)常被使用。 如果字典為空,調用popitem()
將引發(fā)KeyError
。在 3.7 版更改: 現在會(huì )確保采用 LIFO 順序。 在之前的版本中,
popitem()
會(huì )返回一個(gè)任意的鍵/值對。
- reversed(d)
返回一個(gè)逆序獲取字典鍵的迭代器。 這是
reversed(d.keys())
的快捷方式。3.8 新版功能.
- setdefault(key[, default])?
如果字典存在鍵 key ,返回它的值。如果不存在,插入值為 default 的鍵 key ,并返回 default 。 default 默認為
None
。
- update([other])?
使用來(lái)自 other 的鍵/值對更新字典,覆蓋原有的鍵。 返回
None
。update()
接受另一個(gè)字典對象,或者一個(gè)包含鍵/值對(以長(cháng)度為二的元組或其他可迭代對象表示)的可迭代對象。 如果給出了關(guān)鍵字參數,則會(huì )以其所指定的鍵/值對更新字典:d.update(red=1, blue=2)
。
- values()?
返回由字典值組成的一個(gè)新視圖。 參見(jiàn) 視圖對象文檔。
兩個(gè)
dict.values()
視圖之間的相等性比較將總是返回False
。 這在dict.values()
與其自身比較時(shí)也同樣適用:>>> d = {'a': 1} >>> d.values() == d.values() False
- d | other
合并 d 和 other 中的鍵和值來(lái)創(chuàng )建一個(gè)新的字典,兩者必須都是字典。當 d 和 other 有相同鍵時(shí), other 的值優(yōu)先。
3.9 新版功能.
- d |= other
用 other 的鍵和值更新字典 d ,other 可以是 mapping 或 iterable 的鍵值對。當 d 和 other 有相同鍵時(shí), other 的值優(yōu)先。
3.9 新版功能.
兩個(gè)字典的比較當且僅當它們具有相同的
(鍵, 值)
對時(shí)才會(huì )相等(不考慮順序)。 排序比較 ('<', '<=', '>=', '>') 會(huì )引發(fā)TypeError
。字典會(huì )保留插入時(shí)的順序。 請注意對鍵的更新不會(huì )影響順序。 刪除并再次添加的鍵將被插入到末尾。
>>> 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 版更改: 字典順序會(huì )確保為插入順序。 此行為是自 3.6 版開(kāi)始的 CPython 實(shí)現細節。
字典和字典視圖都是可逆的。
>>> 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 版更改: 字典現在是可逆的。
參見(jiàn)
types.MappingProxyType
可被用來(lái)創(chuàng )建一個(gè) dict
的只讀視圖。
字典視圖對象?
由 dict.keys()
, dict.values()
和 dict.items()
所返回的對象是 視圖對象。 該對象提供字典條目的一個(gè)動(dòng)態(tài)視圖,這意味著(zhù)當字典改變時(shí),視圖也會(huì )相應改變。
字典視圖可以被迭代以產(chǎn)生與其對應的數據,并支持成員檢測:
- len(dictview)
返回字典中的條目數。
- iter(dictview)
返回字典中的鍵、值或項(以
(鍵, 值)
為元素的元組表示)的迭代器。鍵和值是按插入時(shí)的順序進(jìn)行迭代的。 這樣就允許使用
zip()
來(lái)創(chuàng )建(值, 鍵)
對:pairs = zip(d.values(), d.keys())
。 另一個(gè)創(chuàng )建相同列表的方式是pairs = [(v, k) for (k, v) in d.items()]
.在添加或刪除字典中的條目期間對視圖進(jìn)行迭代可能引發(fā)
RuntimeError
或者無(wú)法完全迭代所有條目。在 3.7 版更改: 字典順序會(huì )確保為插入順序。
- x in dictview
如果 x 是對應字典中存在的鍵、值或項(在最后一種情況下 x 應為一個(gè)
(鍵, 值)
元組) 則返回True
。
- reversed(dictview)
返回一個(gè)逆序獲取字典鍵、值或項的迭代器。 視圖將按與插入時(shí)相反的順序進(jìn)行迭代。
在 3.8 版更改: 字典視圖現在是可逆的。
- dictview.mapping
返回
types.MappingProxyType
對象,封裝了字典視圖指向的原始字典。3.10 新版功能.
鍵視圖類(lèi)似于集合,因為其條目不重復且可哈希。 如果所有值都是可哈希的,即 (鍵, 值)
對也是不重復且可哈希的,那么條目視圖也會(huì )類(lèi)似于集合。 (值視圖則不被視為類(lèi)似于集合,因其條目通常都是有重復的。) 對于類(lèi)似于集合的視圖,為抽象基類(lèi) collections.abc.Set
所定義的全部操作都是有效的 (例如 ==
, <
或 ^
)。
一個(gè)使用字典視圖的示例:
>>> 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'}
>>> # get back a read-only proxy for the original dictionary
>>> values.mapping
mappingproxy({'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500})
>>> values.mapping['spam']
500
上下文管理器類(lèi)型?
Python 的 with
語(yǔ)句支持通過(guò)上下文管理器所定義的運行時(shí)上下文這一概念。 此對象的實(shí)現使用了一對專(zhuān)門(mén)方法,允許用戶(hù)自定義類(lèi)來(lái)定義運行時(shí)上下文,在語(yǔ)句體被執行前進(jìn)入該上下文,并在語(yǔ)句執行完畢時(shí)退出該上下文:
- contextmanager.__enter__()?
進(jìn)入運行時(shí)上下文并返回此對象或關(guān)聯(lián)到該運行時(shí)上下文的其他對象。 此方法的返回值會(huì )綁定到使用此上下文管理器的
with
語(yǔ)句的as
子句中的標識符。一個(gè)返回其自身的上下文管理器的例子是 file object。 文件對象會(huì )從 __enter__() 返回其自身,以允許
open()
被用作with
語(yǔ)句中的上下文表達式。一個(gè)返回關(guān)聯(lián)對象的上下文管理器的例子是
decimal.localcontext()
所返回的對象。 此種管理器會(huì )將活動(dòng)的 decimal 上下文設為原始 decimal 上下文的一個(gè)副本并返回該副本。 這允許對with
語(yǔ)句的語(yǔ)句體中的當前 decimal 上下文進(jìn)行更改,而不會(huì )影響with
語(yǔ)句以外的代碼。
- contextmanager.__exit__(exc_type, exc_val, exc_tb)?
退出運行時(shí)上下文并返回一個(gè)布爾值旗標來(lái)表明所發(fā)生的任何異常是否應當被屏蔽。 如果在執行
with
語(yǔ)句的語(yǔ)句體期間發(fā)生了異常,則參數會(huì )包含異常的類(lèi)型、值以及回溯信息。 在其他情況下三個(gè)參數均為None
。自此方法返回一個(gè)真值將導致
with
語(yǔ)句屏蔽異常并繼續執行緊隨在with
語(yǔ)句之后的語(yǔ)句。 否則異常將在此方法結束執行后繼續傳播。 在此方法執行期間發(fā)生的異常將會(huì )取代with
語(yǔ)句的語(yǔ)句體中發(fā)生的任何異常。傳入的異常絕對不應當被顯式地重新引發(fā) —— 相反地,此方法應當返回一個(gè)假值以表明方法已成功完成并且不希望屏蔽被引發(fā)的異常。 這允許上下文管理代碼方便地檢測
__exit__()
方法是否確實(shí)已失敗。
Python 定義了一些上下文管理器來(lái)支持簡(jiǎn)易的線(xiàn)程同步、文件或其他對象的快速關(guān)閉,以及更方便地操作活動(dòng)的十進(jìn)制算術(shù)上下文。 除了實(shí)現上下文管理協(xié)議以外,不同類(lèi)型不會(huì )被特殊處理。 請參閱 contextlib
模塊查看相關(guān)的示例。
Python's generators and the contextlib.contextmanager
decorator
provide a convenient way to implement these protocols. If a generator function is
decorated with the contextlib.contextmanager
decorator, it will return a
context manager implementing the necessary __enter__()
and
__exit__()
methods, rather than the iterator produced by an
undecorated generator function.
請注意,Python/C API 中 Python 對象的類(lèi)型結構中并沒(méi)有針對這些方法的專(zhuān)門(mén)槽位。 想要定義這些方法的擴展類(lèi)型必須將它們作為普通的 Python 可訪(fǎng)問(wèn)方法來(lái)提供。 與設置運行時(shí)上下文的開(kāi)銷(xiāo)相比,單個(gè)類(lèi)字典查找的開(kāi)銷(xiāo)可以忽略不計。
類(lèi)型注解的類(lèi)型 --- Generic Alias 、 Union?
type annotations 的內置類(lèi)型為 Generic Alias 和 Union。
GenericAlias 類(lèi)型?
GenericAlias
objects are generally created by
subscripting a class. They are most often used with
container classes, such as list
or
dict
. For example, list[int]
is a GenericAlias
object created
by subscripting the list
class with the argument int
.
GenericAlias
objects are intended primarily for use with
type annotations.
備注
It is generally only possible to subscript a class if the class implements
the special method __class_getitem__()
.
A GenericAlias
object acts as a proxy for a generic type,
implementing parameterized generics.
For a container class, the
argument(s) supplied to a subscription of the class may
indicate the type(s) of the elements an object contains. For example,
set[bytes]
can be used in type annotations to signify a set
in
which all the elements are of type bytes
.
For a class which defines __class_getitem__()
but is not a
container, the argument(s) supplied to a subscription of the class will often
indicate the return type(s) of one or more methods defined on an object. For
example, regular expressions
can be used on both the str
data
type and the bytes
data type:
If
x = re.search('foo', 'foo')
,x
will be a re.Match object where the return values ofx.group(0)
andx[0]
will both be of typestr
. We can represent this kind of object in type annotations with theGenericAlias
re.Match[str]
.If
y = re.search(b'bar', b'bar')
, (note theb
forbytes
),y
will also be an instance ofre.Match
, but the return values ofy.group(0)
andy[0]
will both be of typebytes
. In type annotations, we would represent this variety of re.Match objects withre.Match[bytes]
.
GenericAlias
objects are instances of the class
types.GenericAlias
, which can also be used to create GenericAlias
objects directly.
- T[X, Y, ...]
Creates a
GenericAlias
representing a typeT
parameterized by types X, Y, and more depending on theT
used. For example, a function expecting alist
containingfloat
elements:def average(values: list[float]) -> float: return sum(values) / len(values)
另一個(gè)例子是關(guān)于 mapping 對象的,用到了
dict
,泛型的兩個(gè)類(lèi)型參數分別代表了鍵類(lèi)型和值類(lèi)型。本例中的函數需要一個(gè)dict
,其鍵的類(lèi)型為str
,值的類(lèi)型為int
:。def send_post_request(url: str, body: dict[str, int]) -> None: ...
內置函數 isinstance()
和 issubclass()
不接受第二個(gè)參數為``GenericAlias`` 類(lèi)型:
>>> 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
The Python runtime does not enforce type annotations.
This extends to generic types and their type parameters. When creating
a container object from a GenericAlias
, the elements in the container are not checked
against their type. For example, the following code is discouraged, but will
run without errors:
>>> t = list[str]
>>> t([1, 2, 3])
[1, 2, 3]
不僅如此,在創(chuàng )建對象的過(guò)程中,應用了參數后的泛型還會(huì )抹除類(lèi)型參數:
>>> t = list[str]
>>> type(t)
<class 'types.GenericAlias'>
>>> l = t()
>>> type(l)
<class 'list'>
在泛型上調用 repr()
或 str()
會(huì )顯示應用參數之后的類(lèi)型:
>>> repr(list[int])
'list[int]'
>>> str(list[int])
'list[int]'
The __getitem__()
method of generic containers will raise an
exception to disallow mistakes like dict[str][str]
:
>>> dict[str][str]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: There are no type variables left in dict[str]
However, such expressions are valid when type variables are
used. The index must have as many elements as there are type variable items
in the GenericAlias
object's __args__
.
>>> from typing import TypeVar
>>> Y = TypeVar('Y')
>>> dict[str, Y][int]
dict[str, int]
Standard Generic Classes?
The following standard library classes support parameterized generics. This list is non-exhaustive.
Special Attributes of GenericAlias
objects?
應用參數后的泛型都實(shí)現了一些特殊的只讀屬性:
- genericalias.__origin__?
本屬性指向未應用參數之前的泛型類(lèi):
>>> list[int].__origin__ <class 'list'>
- genericalias.__args__?
This attribute is a
tuple
(possibly of length 1) of generic types passed to the original__class_getitem__()
of the generic class:>>> dict[str, list[int]].__args__ (<class 'str'>, list[int])
- genericalias.__parameters__?
該屬性是延遲計算出來(lái)的一個(gè)元組(可能為空),包含了
__args__
中的類(lèi)型變量。>>> from typing import TypeVar >>> T = TypeVar('T') >>> list[T].__parameters__ (~T,)
備注
帶有參數
typing.ParamSpec
的GenericAlias
對象,在類(lèi)型替換后其__parameters__
可能會(huì )不準確,因為typing.ParamSpec
主要用于靜態(tài)類(lèi)型檢查。
- genericalias.__unpacked__?
A boolean that is true if the alias has been unpacked using the
*
operator (seeTypeVarTuple
).3.11 新版功能.
參見(jiàn)
- PEP 484 - Type Hints
Introducing Python's framework for type annotations.
- PEP 585 - Type Hinting Generics In Standard Collections
Introducing the ability to natively parameterize standard-library classes, provided they implement the special class method
__class_getitem__()
.- 泛型(Generic), user-defined generics and
typing.Generic
Documentation on how to implement generic classes that can be parameterized at runtime and understood by static type-checkers.
3.9 新版功能.
union 類(lèi)型?
聯(lián)合對象包含了在多個(gè) 類(lèi)型對象 上執行 |
(按位或) 運算后的值。 這些類(lèi)型主要用于 類(lèi)型標注。與 typing.Union
相比,聯(lián)合類(lèi)型表達式可以實(shí)現更簡(jiǎn)潔的類(lèi)型提示語(yǔ)法。
- X | Y | ...
定義包含了 X、Y 等類(lèi)型的 union 對象。
X | Y
表示 X 或 Y。相當于``typing.Union[X, Y]`` 。比如以下函數的參數應為類(lèi)型int
或float
:def square(number: int | float) -> int | float: return number ** 2
- union_object == other
union 對象可與其他 union 對象進(jìn)行比較。詳細結果如下:
多次組合的結果會(huì )平推:
(int | str) | float == int | str | float
冗余的類(lèi)型會(huì )被刪除:
int | str | int == int | str
在相互比較時(shí),會(huì )忽略順序:
int | str == str | int
與
typing.union
兼容:int | str == typing.Union[int, str]
Optional 類(lèi)型可表示為與
None
的組合。str | None == typing.Optional[str]
- isinstance(obj, union_object)
- issubclass(obj, union_object)
isinstance()
和issubclass()
也支持 union 對象:>>> isinstance("", int | str) True
但不能使用包含 parameterized generics 的 union 對象:
>>> isinstance(1, int | list[int]) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: isinstance() argument 2 cannot contain a parameterized generic
union 對象構成的用戶(hù)類(lèi)型可以經(jīng)由 types.UnionType
訪(fǎng)問(wèn),并可用于 isinstance()
檢查。 而不能由類(lèi)型直接實(shí)例化為對象:
>>> import types
>>> isinstance(int | str, types.UnionType)
True
>>> types.UnionType()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create 'types.UnionType' instances
備注
為了支持 X | Y
語(yǔ)法,類(lèi)型對象加入了 __or__()
方法。若是元類(lèi)已實(shí)現了 __or__()
,union 也可以覆蓋掉:
>>> class M(type):
... def __or__(self, other):
... return "Hello"
...
>>> class C(metaclass=M):
... pass
...
>>> C | int
'Hello'
>>> int | C
int | __main__.C
參見(jiàn)
PEP 604 —— 提出了 X | Y
語(yǔ)法和 union 類(lèi)型。
3.10 新版功能.
其他內置類(lèi)型?
解釋器支持一些其他種類(lèi)的對象。 這些對象大都僅支持一兩種操作。
模塊?
模塊唯一的特殊操作是屬性訪(fǎng)問(wèn): m.name
,這里 m 為一個(gè)模塊而 name 訪(fǎng)問(wèn)定義在 m 的符號表中的一個(gè)名稱(chēng)。 模塊屬性可以被賦值。 (請注意 import
語(yǔ)句嚴格來(lái)說(shuō)也是對模塊對象的一種操作;import foo
不要求存在一個(gè)名為 foo 的模塊對象,而是要求存在一個(gè)對于名為 foo 的模塊的 (永久性) 定義。)
每個(gè)模塊都有一個(gè)特殊屬性 __dict__
。 這是包含模塊的符號表的字典。 修改此字典將實(shí)際改變模塊的符號表,但是無(wú)法直接對 __dict__
賦值 (你可以寫(xiě) m.__dict__['a'] = 1
,這會(huì )將 m.a
定義為 1
,但是你不能寫(xiě) m.__dict__ = {}
)。 不建議直接修改 __dict__
。
內置于解釋器中的模塊會(huì )寫(xiě)成這樣: <module 'sys' (built-in)>
。 如果是從一個(gè)文件加載,則會(huì )寫(xiě)成 <module 'os' from '/usr/local/lib/pythonX.Y/os.pyc'>
。
類(lèi)與類(lèi)實(shí)例?
關(guān)于這些類(lèi)型請參閱 對象、值與類(lèi)型 和 類(lèi)定義。
函數?
函數對象是通過(guò)函數定義創(chuàng )建的。 對函數對象的唯一操作是調用它: func(argument-list)
。
實(shí)際上存在兩種不同的函數對象:內置函數和用戶(hù)自定義函數。 兩者支持同樣的操作(調用函數),但實(shí)現方式不同,因此對象類(lèi)型也不同。
更多信息請參閱 函數定義。
方法?
方法是使用屬性表示法來(lái)調用的函數。 存在兩種形式:內置方法(例如列表的 append()
方法)和類(lèi)實(shí)例方法。 內置方法由支持它們的類(lèi)型來(lái)描述。
如果你通過(guò)一個(gè)實(shí)例來(lái)訪(fǎng)問(wèn)方法(即定義在類(lèi)命名空間內的函數),你會(huì )得到一個(gè)特殊對象: 綁定方法 (或稱(chēng) 實(shí)例方法) 對象。 當被調用時(shí),它會(huì )將 self
參數添加到參數列表。 綁定方法具有兩個(gè)特殊的只讀屬性: m.__self__
操作該方法的對象,而 m.__func__
是實(shí)現該方法的函數。 調用 m(arg-1, arg-2, ..., arg-n)
完全等價(jià)于調用 m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)
。
與函數對象類(lèi)似,綁定方法對象也支持獲取任意屬性。 但是,由于方法屬性實(shí)際上保存于下層的函數對象中 (meth.__func__
),因此不允許設置綁定方法的方法屬性。 嘗試設置方法的屬性將會(huì )導致引發(fā) AttributeError
。 想要設置方法屬性,你必須在下層的函數對象中顯式地對其進(jìn)行設置:
>>> 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'
更多信息請參閱 標準類(lèi)型層級結構。
代碼對象?
代碼對象被具體實(shí)現用來(lái)表示“偽編譯”的可執行 Python 代碼,例如一個(gè)函數體。 它們不同于函數對象,因為它們不包含對其全局執行環(huán)境的引用。 代碼對象由內置的 compile()
函數返回,并可通過(guò)從函數對象的 __code__
屬性從中提取。 另請參閱 code
模塊。
訪(fǎng)問(wèn) __code__
會(huì )觸發(fā) 審計事件 object.__getattr__
,參數為 obj
和 "__code__"
。
可以通過(guò)將代碼對象(而非源碼字符串)傳給 exec()
或 eval()
內置函數來(lái)執行或求值。
更多信息請參閱 標準類(lèi)型層級結構。
類(lèi)型對象?
類(lèi)型對象表示各種對象類(lèi)型。 對象的類(lèi)型可通過(guò)內置函數 type()
來(lái)獲取。 類(lèi)型沒(méi)有特殊的操作。 標準庫模塊 types
定義了所有標準內置類(lèi)型的名稱(chēng)。
類(lèi)型以這樣的寫(xiě)法來(lái)表示: <class 'int'>
。
空對象?
此對象會(huì )由不顯式地返回值的函數所返回。 它不支持任何特殊的操作。 空對象只有一種值 None
(這是個(gè)內置名稱(chēng))。 type(None)()
會(huì )生成同一個(gè)單例。
該對象的寫(xiě)法為 None
。
省略符對象?
此對象常被用于切片 (參見(jiàn) 切片)。 它不支持任何特殊的操作。 省略符對象只有一種值 Ellipsis
(這是個(gè)內置名稱(chēng))。 type(Ellipsis)()
會(huì )生成 Ellipsis
單例。
該對象的寫(xiě)法為 Ellipsis
或 ...
。
未實(shí)現對象?
此對象會(huì )被作為比較和二元運算被應用于它們所不支持的類(lèi)型時(shí)的返回值。 請參閱 比較運算 了解更多信息。 未實(shí)現對象只有一種值 NotImplemented
。 type(NotImplemented)()
會(huì )生成這個(gè)單例。
該對象的寫(xiě)法為 NotImplemented
。
布爾值?
布爾值是兩個(gè)常量對象 False
和 True
。 它們被用來(lái)表示邏輯上的真假(不過(guò)其他值也可被當作真值或假值)。 在數字類(lèi)的上下文中(例如被用作算術(shù)運算符的參數時(shí)),它們的行為分別類(lèi)似于整數 0 和 1。 內置函數 bool()
可被用來(lái)將任意值轉換為布爾值,只要該值可被解析為一個(gè)邏輯值(參見(jiàn)之前的 邏輯值檢測 部分)。
該對象的寫(xiě)法分別為 False
和 True
。
內部對象?
有關(guān)此對象的信息請參閱 標準類(lèi)型層級結構。 其中描述了棧幀對象、回溯對象以及切片對象等等。
特殊屬性?
語(yǔ)言實(shí)現為部分對象類(lèi)型添加了一些特殊的只讀屬性,它們具有各自的作用。 其中一些并不會(huì )被 dir()
內置函數所列出。
- object.__dict__?
一個(gè)字典或其他類(lèi)型的映射對象,用于存儲對象的(可寫(xiě))屬性。
- instance.__class__?
類(lèi)實(shí)例所屬的類(lèi)。
- class.__bases__?
由類(lèi)對象的基類(lèi)所組成的元組。
- definition.__name__?
類(lèi)、函數、方法、描述器或生成器實(shí)例的名稱(chēng)。
- definition.__qualname__?
類(lèi)、函數、方法、描述器或生成器實(shí)例的 qualified name。
3.3 新版功能.
- class.__mro__?
此屬性是由類(lèi)組成的元組,在方法解析期間會(huì )基于它來(lái)查找基類(lèi)。
- class.mro()?
此方法可被一個(gè)元類(lèi)來(lái)重載,以為其實(shí)例定制方法解析順序。 它會(huì )在類(lèi)實(shí)例化時(shí)被調用,其結果存儲于
__mro__
之中。
- class.__subclasses__()?
每個(gè)類(lèi)都存有對直接子類(lèi)的弱引用列表。本方法返回所有存活引用的列表。列表的順序按照子類(lèi)定義的排列。例如:
>>> int.__subclasses__() [<class 'bool'>]
備注
- 1
有關(guān)這些特殊方法的額外信息可參看 Python 參考指南 (基本定制)。
- 2
作為結果,列表
[1, 2]
與[1.0, 2.0]
是相等的,元組的情況也類(lèi)似。- 3
必須如此,因為解析器無(wú)法判斷操作數的類(lèi)型。
- 4(1,2,3,4)
區分大小寫(xiě)的字符是指所屬一般類(lèi)別屬性為 "Lu" (Letter, uppercase), "Ll" (Letter, lowercase) 或 "Lt" (Letter, titlecase) 之一的字符。
- 5(1,2)
若只是要格式化一個(gè)元組,則應提供一個(gè)單例元組,其中只包含一個(gè)元素,就是需要格式化的那個(gè)元組。