5. Built-in Types

以下各节描述了解释器中内置的标准类型。

Note

历史上(直到 2.2 版),Python 的内置类型与用户定义的类型有所不同,因为无法将内置类型用作面向对象继承的基础。此限制不再存在。

内置的主要类型是数字,序列,Map,文件,类,实例和异常。

一些对象类型支持某些操作。特别是,几乎所有对象都可以进行比较,测试真值并转换为字符串(使用repr()函数或稍有不同的str()函数)。当passprint()函数写入对象时,隐式使用后一个函数。

5.1. 真值测试

可以测试任何对象的真值,以用于ifwhile条件或用作以下布尔运算的操作数。以下值为“假”:

Note

所有其他值都被认为是真实的-因此许多类型的对象总是真实的。

除非另有说明,否则具有布尔结果的操作和内置函数始终返回0False代表 false,返回1True代表 true。 (重要的 exception:布尔运算orand始终返回其操作数之一.)

5.2. 布尔运算-和,或不

这些是布尔运算,按优先级升序排列:

Operation Result Notes
x or y 如果* x 为假,则 y ,否则 x * (1)
x and y 如果* x 为假,则 x ,否则 y * (2)
not x 如果* x *为假,则True,否则False (3)

Notes:

5.3. Comparisons

所有对象都支持比较操作。它们都具有相同的优先级(高于布尔运算的优先级)。比较可以任意链接;例如,x < y <= z等效于x < y and y <= z,除了* y 仅被评估一次(但在两种情况下,如果x < y被发现为假,则根本不评估 z *)。

下表总结了比较操作:

Operation Meaning Notes
< 严格小于
<= 小于或等于
> 严格大于
>= 大于或等于
== equal
!= not equal (1)
is object identity
is not 否定对象身份

Notes:

不同类型的对象(不同的数字类型和不同的字符串类型除外)绝不会相等。这样的对象可以一致但任意地排序(以便对异构数组进行排序可以得到一致的结果)。此外,某些类型(例如文件对象)仅支持简并的比较概念,其中该类型的任何两个对象都不相等。同样,这些对象是任意但一致地排序的。当任何操作数为复数时,<<=>>=运算符将引发TypeError异常。

通常,除非类定义eq()方法或cmp()方法,否则类的不同实例通常比较为不相等。

一个类的实例不能相对于同一类的其他实例或其他类型的对象进行排序,除非该类定义了足够的丰富比较方法(lt()le()gt()ge())或cmp()方法。

CPython 实现细节: 不同类型的对象(数字除外)按其类型名称排序;不支持正确比较的相同类型的对象按其地址排序。

语法类型相同的另外两个操作innot in仅受序列类型(以下)支持。

5.4. 数值类型-整型,浮点型,长整型

有四种不同的数字类型:普通整数长整数浮点数复数。另外,布尔值是纯整数的子类型。普通整数(也称为* integers )是使用 C 语言中的long实现的,这使它们至少具有 32 位精度(对于当前平台,sys.maxint始终设置为最大普通整数值,最小值是-sys.maxint - 1)。长整数具有无限的精度。浮点数通常在 C 语言中使用double来实现; sys.float_info中提供了有关运行程序的计算机的浮点数的精度和内部表示形式的信息。复数具有实部和虚部,每个均是浮点数。要从复数 z *中提取这些部分,请使用z.realz.imag。 (标准库包括其他数字类型,具有逻辑的fractions和具有用户可定义精度的浮点数的decimal。)

数字是pass数字 Literals 或内置函数和运算符创建的。未经修饰的整数 Literals(包括二进制,十六进制和八进制数字)将生成纯整数,除非它们所表示的值太大而无法表示为纯整数,在这种情况下,它们将生成一个长整数。带'L''l'后缀的整数 Literals 会产生长整数(首选'L',因为1l看起来很像 11!)。包含小数点或指数符号的数字 Literals 会产生浮点数。将'j''J'附加到数字 Literals 会产生虚数(实数为零的复数),您可以将其添加到整数或浮点数以获得具有实数和虚数的复数。

Python 完全支持混合算术:当二进制算术运算符具有不同数值类型的操作数时,具有“更窄”类型的操作数将扩展为另一种,其中普通整数窄于长整数窄于浮点窄于整数复杂。混合类型数之间的比较使用相同的规则。 [2]构造函数int()long()float()complex()可用于生成特定类型的数字。

所有内置数字类型均支持以下操作。有关操作员的优先级,请参见power operator和后续部分。

Operation Result Notes
x + y * x y *的总和
x - y * x y *之差
x * y * x y *的乘积
x / y * x y *的商 (1)
x // y * x y *的(乘积)商 (4)(5)
x % y x / y的余数 (4)
-x * x *否定
+x * x *不变
abs(x) * x *的绝对值或大小 (3)
int(x) * x *转换为整数 (2)
long(x) * x *转换为长整数 (2)
float(x) * x *转换为浮点 (6)
complex(re,im) 具有实数部分* re ,虚数部分 im *的复数。 * im *默认为零。
c.conjugate() 复数* c *的共轭。 (实数身份)
divmod(x, y) Pair(x // y, x % y) (3)(4)
pow(x, y) * x 为幂 y * (3)(7)
x ** y * x 为幂 y * (7)

Notes:

2.6 版的新Function。

所有numbers.Real类型(intlongfloat)还包括以下操作:

Operation Result
math.trunc(x) * x *被截断为Integral
round(x[, n]) * x 四舍五入为 n 个数字,四舍五入以零为单位。如果Ellipsis n *,则默认为 0.
math.floor(x) 浮点数最大的整数<= * x *
math.ceil(x) 浮点数的最小整数> = * x *

5.4.1. 整数类型的按位运算

按位运算仅对整数有意义。负数被视为其 2 的补码值(这假设有足够多的位,因此在操作期间不会发生溢出)。

二进制按位运算的优先级均低于数字运算,且高于比较运算。一元运算~与其他一元数值运算(+-)具有相同的优先级。

下表列出了按优先级升序排列的按位运算:

Operation Result Notes
x | y * x y 的按位 or *
x ^ y * x y *的按位“异或” *
x & y * x y 的按位 and *
x << n * x 向左移动 n *位 (1)(2)
x >> n * x 向右移动 n *位 (1)(3)
~x * x *的位倒置

Notes:

5.4.2. 整数类型的其他方法

整数类型实现numbers.Integral 抽象 Base Class。此外,它们还提供了另一种方法:

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

更准确地说,如果x为非零,则x.bit_length()是唯一的正整数k,使得2**(k-1) <= abs(x) < 2**k。等效地,当abs(x)小到足以具有正确舍入的对数时,则k = 1 + int(log(abs(x), 2))。如果x为零,则x.bit_length()返回0

Equivalent to:

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

2.7 版的新Function。

5.4.3. 浮点数的其他方法

浮点类型实现numbers.Real 抽象 Base Class。 float 还具有以下其他方法。

2.6 版的新Function。

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

2.6 版的新Function。

有两种方法支持与十六进制字符串之间的转换。由于 Python 的浮点数在内部存储为二进制数字,因此,将浮点数与* decimal *字符串进行相互转换通常会产生较小的舍入误差。相反,十六进制字符串允许精确表示和指定浮点数。这在调试和数值工作时很有用。

2.6 版的新Function。

2.6 版的新Function。

请注意,float.hex()是实例方法,而float.fromhex()是类方法。

十六进制字符串的形式为:

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

其中可选的sign可以是+-integerfraction是十六进制数字的字符串,而exponent是带有可选前导符号的十进制整数。大小写无关紧要,并且整数或分数中必须至少有一个十六进制数字。此语法与 C99 标准的 6.4.4.2 节中指定的语法相似,也与 Java 1.5 及更高版本中使用的语法相似。特别地,float.hex()的输出可用作 C 或 Java 代码中的十六进制浮点 Literals,并且float.fromhex()接受 C 的%a格式字符或 Java 的Double.toHexString产生的十六进制字符串。

请注意,指数用十进制而不是十六进制表示,并且乘以 2 的幂乘以系数。例如,十六进制字符串0x3.a7p10表示浮点数(3 + 10./16 + 7./16**2) * 2.0**103740.0

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

将反向转换应用于3740.0会给出不同的十六进制字符串,表示相同的数字:

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

5.5. 迭代器类型

2.2 版中的新Function。

Python 支持容器迭代的概念。这是pass两种不同的方法实现的:这些用于允许用户定义的类支持迭代。下面更详细描述的序列始终支持迭代方法。

需要为容器对象定义一种方法以提供迭代支持:

需要迭代器对象本身支持以下两种方法,它们共同构成* iterator 协议*:

Python 定义了几个迭代器对象,以支持对常规和特定序列类型,字典以及其他更专门形式的迭代。除了其迭代器协议的实现之外,特定类型并不重要。

该协议的目的是,一旦迭代器的next()方法引发StopIteration,它将在后续调用中 continue 这样做。不遵守此属性的实现被视为已损坏。 (在 Python 2.3 中添加了此约束;在 Python 2.2 中,根据此规则破坏了各种迭代器.)

5.5.1. Generator 类型

Python 的generator提供了一种实现迭代器协议的便捷方法。如果将容器对象的iter()方法实现为生成器,它将自动返回提供iter()next()方法的迭代器对象(从技术上讲,是生成器对象)。有关生成器的更多信息,请参见yield表达文件

5.6. 序列类型— str,unicode,list,tuple,bytearray,buffer,xrange

有七种序列类型:字符串,Unicode 字符串,列表,Tuples,字节数组,缓冲区和 xrange 对象。

对于其他容器,请参见内置的dictset类以及collections模块。

字符串 Literals 用单引号或双引号引起来:'xyzzy'"frobozz"。有关字符串 Literals 的更多信息,请参见String literals。 Unicode 字符串与字符串非常相似,但是在语法中使用前面的'u'字符:u'abc'u"def"指定。除了此处描述的Function外,在String Methods部分中还描述了特定于字符串的方法。列表用方括号构成,用逗号分隔项目:[a, b, c]。Tuples 由逗号运算符构造(不在方括号内),带有或不带有括号,但是空的 tuple 必须带有括号,例如a, b, c()。单个项目 Tuples 必须带有尾随逗号,例如(d,)

字节数组对象是使用内置函数bytearray()创建的。

缓冲区对象不受 Python 语法的直接支持,但可以pass调用内置函数buffer()来创建。他们不支持串联或重复。

xrange 类型的对象与缓冲区类似,因为没有特定的语法可以创建它们,但是它们是使用xrange()函数创建的。它们不支持切片,连接或重复,并且在它们上使用innot inmin()max()效率低下。

大多数序列类型支持以下操作。 innot in操作具有与比较操作相同的优先级。 +*运算与相应的数字运算具有相同的优先级。 [3]可变序列类型提供了其他方法。

下表列出了按优先级升序排列的序列操作。在表中,* s t *是相同类型的序列; * n i j *是整数:

Operation Result Notes
x in s True如果* s 的项等于 x *,否则False (1)
x not in s False如果* s 的项等于 x *,否则True (1)
s + t * s t *的串联 (6)
s * n, n * s 相当于将* s 加到自身 n *次 (2)
s[i] * s i *个项,原点 0 (3)
s[i:j] 从* i j s *切片 (3)(4)
s[i:j:k] 从* i j s 切片,步为 k * (3)(5)
len(s) * s *的长度
min(s) * s *的最小项
max(s) * s *的最大项
s.index(x) * s 中第一次出现的 x *的索引
s.count(x) * s x *的出现总数

序列类型也支持比较。特别是,pass比较相应的元素按字典 Sequences 比较 Tuples 和列表。这意味着要进行相等比较,每个元素必须进行相等比较,并且两个序列必须具有相同的类型并且具有相同的长度。 (有关详细信息,请参见语言参考中的Comparisons。)

Notes:

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

发生的事情是[[]]是一个包含一个空列表的单元素列表,因此[[]] * 3的所有三个元素都是对该单个空列表的引用。修改lists的任何元素都将修改此单个列表。您可以pass以下方式创建不同列表的列表:

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

常见问题解答条目如何创建多维列表?中提供了更多说明。

在版本 2.4 中进行了更改:以前,字符串连接从未就位发生。

5.6.1. 字符串方法

下面列出了 8 位字符串和 Unicode 对象都支持的字符串方法。其中一些也可以在bytearray个对象上使用。

另外,Python 的字符串支持序列类型— str,unicode,list,tuple,bytearray,buffer,xrange部分中描述的序列类型方法。要输出格式化的字符串,请使用模板字符串或字符串格式化操作部分中所述的%运算符。另外,有关基于正则表达式的字符串函数,请参见re模块。

对于 8 位字符串,此方法与语言环境有关。

在版本 2.4 中更改:支持* fillchar *参数。

2.2 版中的新Function。

在版本 2.3 中进行了更改:添加了对其他错误处理方案的支持。

在 2.7 版中进行了更改:添加了对关键字参数的支持。

2.0 版中的新Function。

在版本 2.3 中进行了更改:添加了对'xmlcharrefreplace''backslashreplace'的支持以及其他错误处理方案。

在 2.7 版中进行了更改:添加了对关键字参数的支持。

在版本 2.5 中进行了更改:将 Tuples 接受为后缀

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

Note

仅当您需要知道* sub 的位置时,才应使用find()方法。要检查 sub *是否为子字符串,请使用in运算符:

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

有关可以在格式字符串中指定的各种格式选项的说明,请参见格式字符串语法

这种字符串格式设置方法是 Python 3 中的新标准,并且应优先于新代码中字符串格式化操作中描述的%格式。

2.6 版的新Function。

对于 8 位字符串,此方法与语言环境有关。

对于 8 位字符串,此方法与语言环境有关。

对于 8 位字符串,此方法与语言环境有关。

对于 8 位字符串,此方法与语言环境有关。

对于 8 位字符串,此方法与语言环境有关。

对于 8 位字符串,此方法与语言环境有关。

对于 8 位字符串,此方法与语言环境有关。

在版本 2.4 中更改:支持* fillchar *参数。

对于 8 位字符串,此方法与语言环境有关。

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

在版本 2.2.2 中更改:支持* chars *参数。

2.5 版的新Function。

在版本 2.4 中更改:支持* fillchar *参数。

2.5 版的新Function。

2.4 版的新Function。

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

在版本 2.2.2 中更改:支持* chars *参数。

如果给定* sep *,则不将连续的定界符分组在一起,并且将其视为定界空字符串(例如'1,,2'.split(',')返回['1', '', '2'])。 * sep *参数可以包含多个字符(例如'1<>2<>3'.split('<>')返回['1', '2', '3'])。使用指定的分隔符分割空字符串将返回['']

如果未指定* sep *或为None,则将应用不同的拆分算法:连续的空白行被视为单个分隔符,并且如果字符串的开头或结尾处有空格,则结果在开头或结尾将不包含空字符串。因此,使用None分隔符拆分空字符串或仅包含空格的字符串将返回[]

例如,' 1 2 3 '.split()返回['1', '2', '3'],而' 1 2 3 '.split(None, 1)返回['1', '2 3 ']

Python 将"\r""\n""\r\n"识别为 8 位字符串的行边界。

For example:

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

split()不同,当给出分隔符* sep *时,此方法返回空字符串的空列表,并且终端换行不会导致多余的行:

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

为了进行比较,split('\n')给出:

>>> ''.split('\n')
['']
>>> 'Two lines\n'.split('\n')
['Two lines', '']
Representation Description
\n Line Feed
\r Carriage Return
\r\n 回车换行
\v\x0b Line Tabulation
\f\x0c Form Feed
\x1c File Separator
\x1d Group Separator
\x1e Record Separator
\x85 下一行(C1 控制码)
\u2028 Line Separator
\u2029 Paragraph Separator

在 2.7 版中进行了更改:\v\f已添加到行边界列表中。

在版本 2.5 中更改:将 Tuples 接受为* prefix *。

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

在版本 2.2.2 中更改:支持* chars *参数。

对于 8 位字符串,此方法与语言环境有关。

该算法使用单词的简单语言独立定义作为连续字母的组。该定义在许多情况下都适用,但是它意味着缩略语和所有格中的撇号形成单词边界,这可能不是期望的结果:

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

撇号的变通办法可以使用正则表达式构造:

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

对于 8 位字符串,此方法与语言环境有关。

您可以使用string模块中的maketrans()辅助函数来创建翻译表。对于字符串对象,对于仅删除字符的翻译,将* table *参数设置为None

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

2.6 版的新Function:支持None * table *参数。

对于 Unicode 对象,translate()方法不接受可选的* deletechars 参数。相反,它返回 s *的副本,其中所有字符都已pass给定的转换表进行 Map,该表必须是 Unicode 序号到 Unicode 序号,Unicode 字符串或None的 Map。未 Map 的字符保持不变。Map 到None的字符将被删除。请注意,更灵活的方法是使用codecs模块创建自定义字符 Map 编解码器(有关示例,请参见encodings.cp1251)。

对于 8 位字符串,此方法与语言环境有关。

版本 2.2.2 中的新Function。

以下方法仅在 unicode 对象上存在:

5.6.2. 字符串格式化操作

字符串和 Unicode 对象具有一个唯一的内置操作:%运算符(模)。这也称为字符串* formatting interpolation 运算符。给定format % values(其中 format 是字符串或 Unicode 对象),将 format 中的%转换规范替换为 values 的零个或多个元素。效果类似于在 C 语言中使用sprintf()。如果 format *是 Unicode 对象,或者使用%s转换转换的任何对象是 Unicode 对象,则结果也将是 Unicode 对象。

如果* format 需要单个参数,则 values *可以是单个非 Tuples 对象。 [5]否则,“值”必须是一个具有由格式字符串指定的项目数完全相同的 Tuples,或者是单个 Map 对象(例如,词典)。

转换说明符包含两个或多个字符,并具有以下组件,这些组件必须按此 Sequences 出现:

当正确的参数是字典(或其他 Map 类型)时,字符串必须的格式必须在该字典中包含括号的 Map 键,该键直接插入'%'字符后。Map 键从 Map 中选择要格式化的值。例如:

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

在这种情况下,*1 指定符不能以某种格式出现(因为它们需要 Sequences 的参数列表)。

转换标志字符为:

Flag Meaning
'#' 值转换将使用“替代形式”(在下面定义)。
'0' 对于数值,转换将被零填充。
'-' 转换后的值将进行左调整(如果同时给出'0'转换,则将被覆盖)。
' ' (空格)在带符号的转换产生的正数(或空字符串)之前应留一个空格。
'+' 在转换之前将使用符号字符('+''-')(覆盖“空格”标志)。

长度修饰符(hlL)可能存在,但由于 Python 不必要而被忽略-例如%ld%d相同。

转换类型为:

Conversion Meaning Notes
'd' 有符号整数十进制。
'i' 有符号整数十进制。
'o' 有符号八进制值。 (1)
'u' 过时的类型–与'd'相同。 (7)
'x' 有符号十六进制(小写)。 (2)
'X' 有符号十六进制(大写)。 (2)
'e' 浮点指数格式(小写)。 (3)
'E' 浮点指数格式(大写)。 (3)
'f' 浮点十进制格式。 (3)
'F' 浮点十进制格式。 (3)
'g' 浮点格式。如果指数小于-4 或不小于精度,则使用小写的指数格式,否则使用十进制格式。 (4)
'G' 浮点格式。如果指数小于-4 或不小于精度,则使用大写指数格式,否则使用十进制格式。 (4)
'c' 单个字符(接受整数或单个字符串)。
'r' 字符串(使用repr()转换任何 Python 对象)。 (5)
's' 字符串(使用str()转换任何 Python 对象)。 (6)
'%' 不转换任何参数,结果为'%'字符。

Notes:

精度确定小数点后的位数,默认为 6.

精度确定小数点前后的有效位数,默认为 6.

精度确定使用的最大字符数。

精度确定使用的最大字符数。

由于 Python 字符串具有明确的长度,因此%s转换不假定'\0'是字符串的结尾。

在 2.7 版中进行了更改:绝对值超过 1e50 的数字的%f转换不再由%g转换代替。

在标准模块stringre中定义了其他字符串操作。

5.6.3. XRange 类型

xrange类型是不可变的序列,通常用于循环。 xrange类型的优点是xrange对象将始终占用相同的内存量,无论它表示的范围大小如何。没有一致的性能优势。

XRange 对象的行为很少:它们仅支持索引,迭代和len()函数。

5.6.4. 可变序列类型

列表和bytearray对象支持允许对对象进行就地修改的其他操作。其他可变序列类型(添加到语言中时)也应支持这些操作。字符串和 Tuples 是不可变的序列类型:此类对象一旦创建就无法修改。在可变序列类型(其中* x *是任意对象)上定义了以下操作:

Operation Result Notes
s[i] = x * s 的项 i x *代替
s[i:j] = t 从* i j s 切片被可迭代 t *的内容替换
del s[i:j] s[i:j] = []相同
s[i:j:k] = t s[i:j:k]的元素被* t *的元素替换 (1)
del s[i:j:k] 从列表中删除s[i:j:k]的元素
s.append(x) s[len(s):len(s)] = [x]相同 (2)
s.extend(t)s += t 大部分与s[len(s):len(s)] = t相同 (3)
s *= n 更新* s ,其内容重复 n *次 (11)
s.count(x) 返回s[i] == x的* i *的数量
s.index(x[, i[, j]]) 返回最小的* k *,使得s[k] == xi <= k < j (4)
s.insert(i, x) s[i:i] = [x]相同 (5)
s.pop([i]) x = s[i]; del s[i]; return x相同 (6)
s.remove(x) del s[s.index(x)]相同 (4)
s.reverse() 反转* s *的项目 (7)
s.sort([cmp[, key[, reverse]]]) 将* s *的项目排序到位 (7)(8)(9)(10)

Notes:

在版本 2.3 中进行了更改:以前,index()没有用于指定开始位置和停止位置的参数。

在版本 2.3 中进行了更改:以前,所有负索引都被截断为零。

通常,* key reverse 转换过程比指定等效的 cmp 函数要快得多。这是因为 cmp 被每个列表元素多次调用,而 key reverse 仅触摸每个元素一次。使用functools.cmp_to_key()将旧式 cmp 函数转换为 key *函数。

在版本 2.3 中进行了更改:添加了对None的支持,等同于Ellipsis了* cmp *。

在版本 2.4 中更改:添加了对* key reverse *的支持。

5.7. 集合类型-集合,frozenset

2.4 版的新Function。

与其他集合一样,集合支持x in setlen(set)for x in set。集是无序集合,不记录元素位置或插入 Sequences。因此,集合不支持索引,切片或其他类似序列的行为。

当前有两种内置集类型setfrozensetset类型是可变的-可以使用add()remove()之类的方法更改内容。由于它是可变的,因此它没有哈希值,因此不能用作字典键或另一个集合的元素。 frozenset类型是不可变的,而hashable类型-创建后不能更改其内容;因此,它可以用作字典键或用作另一个集合的元素。

从 Python 2.7 开始,可以pass在括号内放置以逗号分隔的元素列表来创建非空集(非冻结集),例如:set构造函数之外的{'jack', 'sjoerd'}

这两个类的构造函数工作相同:

setfrozenset的实例提供以下操作:

2.6 版的新Function。

在 2.6 版中更改:接受多个 Importing 可迭代项。

在 2.6 版中更改:接受多个 Importing 可迭代项。

在 2.6 版中更改:接受多个 Importing 可迭代项。

请注意,union()intersection()difference()以及symmetric_difference()issubset()issuperset()方法的非运算符版本将接受任何 iterable 作为参数。相反,其基于运算符的对应项要求将其参数设置为。这就避免了像set('abc') & 'cbs'这样的易于出错的结构,而采用了更具可读性的set('abc').intersection('cbs')

setfrozenset支持均设置为设置比较。当且仅当每个集合的每个元素都包含在另一个集合中(每个元素是另一个子集)时,两个集合才相等。当且仅当第一集合是第二集合的适当子集(是子集,但不相等)时,一个集合小于另一个集合。当且仅当第一个集合是第二个集合的适当超集(是一个超集,但不相等)时,一个集合才大于另一个集合。

set实例将根据其成员与frozenset实例进行比较。例如,set('abc') == frozenset('abc')返回Trueset('abc') in set([frozenset('abc')])也返回。

子集和相等性比较不能推广到总排序Function。例如,任何两个非空的不交集都不相等,也不是彼此的子集,因此以下的“全部”返回Falsea<ba==ba>b。因此,集合不实现cmp()方法。

由于集合仅定义部分排序(子集关系),因此对于集合列表未定义list.sort()方法的输出。

集合元素(例如字典键)必须为hashable

set个实例与frozenset混合的二进制运算返回第一个操作数的类型。例如:frozenset('ab') | set('bc')返回frozenset的实例。

下表列出了适用于set的操作,不适用于frozenset的不可变实例:

在 2.6 版中更改:接受多个 Importing 可迭代项。

在 2.6 版中更改:接受多个 Importing 可迭代项。

在 2.6 版中更改:接受多个 Importing 可迭代项。

请注意,update()intersection_update()difference_update()symmetric_difference_update()方法的非运算符版本将接受任何可迭代的参数。

注意,contains()remove()discard()方法的* elem 参数可以是一个集合。为了支持搜索等效的冻结集,从 elem *创建了一个临时集。

See also

5.8. Map 类型— dict

mapping对象将hashable值 Map 到任意对象。Map 是可变的对象。当前只有一种标准 Map 类型* dictionary *。 (有关其他容器,请参见内置的listsettuple类以及collections模块。)

词典的键几乎是任意值。非hashable的值,即包含列表,字典或其他可变类型的值(按值而不是对象标识进行比较)不得用作键。用于键的数字类型遵循数字比较的一般规则:如果两个数字比较相等(例如11.0),则可以互换使用它们来索引相同的字典条目。 (但是请注意,由于计算机将浮点数存储为近似值,因此将它们用作字典键通常是不明智的.)

可以pass在括号中放置key: value对的逗号分隔列表(例如{'jack': 4098, 'sjoerd': 4127}{4098: 'jack', 4127: 'sjoerd'})或dict构造函数来创建字典。

如果没有给出位置参数,则创建一个空字典。如果给出了位置参数并且它是一个 Map 对象,则将使用与该 Map 对象相同的键值对创建一个字典。否则,位置参数必须是iterable对象。可迭代对象中的每个项目本身都必须是具有两个对象的可迭代对象。每个项目的第一个对象成为新字典中的键,第二个对象成为相应的值。如果某个键多次出现,则该键的最后一个值将成为新字典中的相应值。

如果给出了关键字参数,则关键字参数及其值将添加到根据位置参数创建的字典中。如果已经存在要添加的键,则关键字自变量中的值将替换位置自变量中的值。

为了说明,以下示例均返回等于{"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})
>>> a == b == c == d == e
True

如第一个示例中那样,提供关键字参数仅适用于有效的 Python 标识符的键。否则,可以使用任何有效的密钥。

2.2 版中的新Function。

在版本 2.3 中进行了更改:支持从添加的关键字参数构建字典。

这些是词典支持的操作(因此,自定义 Map 类型也应支持):

如果 dict 的子类定义了方法missing(),并且* key 不存在,则d[key]操作会以键 key *作为参数调用该方法。 d[key]操作然后返回或引发__missing__(key)调用返回或引发的所有内容。没有其他操作或方法调用missing()。如果未定义missing(),则引发KeyErrormissing()必须是一个方法;它不能是实例变量:

>>> class Counter(dict):
...     def __missing__(self, key):
...         return 0
>>> c = Counter()
>>> c['red']
0
>>> c['red'] += 1
>>> c['red']
1

上面的示例显示了collections.Counter的部分实现。 collections.defaultdict使用了不同的__missing__方法。

2.5 版中的新Function:识别 dict 子类的__missing_方法。

2.2 版中的新Function。

2.2 版中的新Function。

fromkeys()是返回新字典的类方法。 默认为None

2.3 版的新Function。

CPython 实现细节: 键和值以任意 Sequences 列出,该 Sequences 是非随机的,在 Python 实现中会有所不同,并且取决于字典的插入和删除历史。

如果调用items()keys()values()iteritems()iterkeys()itervalues()且未对字典进行任何中间修改,则列表将直接对应。这允许使用zip()pairs = zip(d.values(), d.keys())创建(value, key)对。 iterkeys()itervalues()方法具有相同的关系:pairs = zip(d.itervalues(), d.iterkeys())pairs提供相同的值。创建相同列表的另一种方法是pairs = [(v, k) for (k, v) in d.iteritems()]

在字典中添加或删除条目时使用iteritems()可能会引发RuntimeError或无法迭代所有条目。

2.2 版中的新Function。

在字典中添加或删除条目时使用iterkeys()可能会引发RuntimeError或无法迭代所有条目。

2.2 版中的新Function。

在字典中添加或删除条目时使用itervalues()可能会引发RuntimeError或无法迭代所有条目。

2.2 版中的新Function。

2.3 版的新Function。

popitem()对于破坏性地迭代字典很有用,这在集合算法中经常使用。如果字典为空,则调用popitem()会引发KeyError

update()接受另一个字典对象或键/值对的迭代(作为 Tuples 或长度为 2 的其他迭代)。如果指定了关键字参数,则将使用以下键/值对更新字典:d.update(red=1, blue=2)

在版本 2.4 中更改:允许参数是键/值对的迭代,并允许关键字参数。

2.7 版的新Function。

2.7 版的新Function。

2.7 版的新Function。

当且仅当它们具有相同的(key, value)对时,字典才会比较相等。

5.8.1. 字典视图对象

dict.viewkeys()dict.viewvalues()dict.viewitems()返回的对象是* view objects *。它们提供了字典条目的动态视图,这意味着当字典更改时,该视图会反映这些更改。

字典视图可以迭代生成各自的数据,并支持成员资格测试:

键和值以任意 Sequences 进行迭代,该 Sequences 是非随机的,在 Python 实现中会有所不同,并且取决于字典的插入和删除历史。如果对键,值和项视图进行了迭代,而对字典没有任何中间修改,则项的 Sequences 将直接对应。这允许使用zip()pairs = zip(d.values(), d.keys())创建(value, key)对。创建相同列表的另一种方法是pairs = [(v, k) for (k, v) in d.items()]

在字典中添加或删除条目时迭代视图可能会引发RuntimeError或无法迭代所有条目。

键视图是集合式的,因为它们的条目是唯一且可哈希的。如果所有值都是可哈希的,因此(键,值)对是唯一且可哈希的,则项目视图也将类似于集合。 (由于条目通常不是唯一的,因此值视图不会被视为类似集合的对象.)然后可以使用这些集合操作(“其他”是指另一个视图或集合):

字典视图用法的一个示例:

>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.viewkeys()
>>> values = dishes.viewvalues()

>>> # iteration
>>> n = 0
>>> for val in values:
...     n += val
>>> print(n)
504

>>> # keys and values are iterated over in the same order
>>> list(keys)
['eggs', 'bacon', 'sausage', 'spam']
>>> list(values)
[2, 1, 1, 500]

>>> # view objects are dynamic and reflect dict changes
>>> del dishes['eggs']
>>> del dishes['sausage']
>>> list(keys)
['spam', 'bacon']

>>> # set operations
>>> keys & {'eggs', 'bacon', 'salad'}
{'bacon'}

5.9. 文件对象

文件对象是使用 C 的stdio包实现的,并且可以使用内置的open()函数创建。文件对象还由其他一些内置函数和方法返回,例如os.popen()os.fdopen()以及套接字对象的makefile()方法。可以使用tempfile模块创建临时文件,并且可以使用shutil模块实现高级文件操作,例如复制,移动和删除文件和目录。

当文件操作由于与 I/O 相关的原因而失败时,将引发异常IOError。这包括由于某种原因未定义操作的情况,例如 tty 设备上的seek()或写入已打开以供读取的文件。

文件具有以下方法:

从 Python 2.5 开始,如果使用with语句,则可以避免显式调用此方法。例如,当退出with块时,以下代码将自动关闭* f *:

from __future__ import with_statement # This isn't required in Python 2.6

with open("hello.txt") as f:
    for line in f:
        print line,

在旧版本的 Python 中,您需要执行以下操作才能获得相同的效果:

f = open("hello.txt")
try:
    for line in f:
        print line,
finally:
    f.close()

Note

Python 中并非所有“类文件”类型都支持将with语句用作上下文 Management 器。如果您的代码打算与任何类似文件的对象一起使用,则可以使用函数contextlib.closing()代替直接使用该对象。

Note

flush()不一定会将文件的数据写入磁盘。使用flush(),然后使用os.fsync()来确保此行为。

Note

没有真实文件 Descriptors 的类似文件的对象应该提供这种方法!

Note

如果类似文件的对象未与实际文件相关联,则该方法不应实现。

2.3 版的新Function。

Note

此函数只是基础fread() C 函数的包装,并且在极端情况下(例如,是否缓存 EOF 值)的行为相同。

Note

stdiofgets()不同,如果 Importing 中出现空字符('\0'),则返回的字符串包含空字符('\0')。

2.1 版中的新Function。

从 2.3 版开始不推荐使用:改为使用for line in file

例如,f.seek(2, os.SEEK_CUR)将位置前进 2,而f.seek(-3, os.SEEK_END)将位置排在最后一位。

请注意,如果打开文件进行追加(模式'a''a+'),则在下一次写入时将撤消任何seek()操作。如果仅打开文件以在追加模式('a')下进行写入,则此方法本质上是无操作的,但是对于在启用了读取的追加模式('a+')下打开的文件仍然有用。如果以文本模式(不带'b')打开文件,则仅tell()返回的偏移量是合法的。使用其他偏移量会导致未定义的行为。

请注意,并非所有文件对象都是可搜索的。

在 2.6 版中进行了更改:不建议使用将 float 值作为 offset 传递。

Note

在 Windows 上,当以 Unix 样式的行尾读取文件时,tell()可以返回非法值(在fgets()之后)。使用二进制模式('rb')可以解决此问题。

文件支持迭代器协议。每次迭代返回与readline()相同的结果,并且当readline()方法返回空字符串时,迭代结束。

文件对象还提供了许多其他有趣的属性。这些对于类文件的对象不是必需的,但是如果它们对特定对象有意义,则应实现它们。

2.3 版的新Function。

2.6 版的新Function。

Note

此属性不是用来控制print语句,而是允许print的实现跟踪其内部状态。

5.10. memoryview 类型

2.7 版的新Function。

memoryview对象允许 Python 代码无需复制即可访问支持缓冲区协议的对象的内部数据。内存通常被解释为简单字节。

memoryview具有* element 的概念,它是由原始对象 obj *处理的原子存储单元。对于许多简单类型,例如strbytearray,元素是一个字节,但是其他第三方类型可能会公开较大的元素。

len(view)返回 memoryview 中的元素总数* view *。 itemsize属性将为您提供单个元素中的字节数。

memoryview支持切片以公开其数据。取得单个索引将返回单个元素作为str对象。完整切片将产生一个子视图:

>>> v = memoryview('abcefg')
>>> v[1]
'b'
>>> v[-1]
'g'
>>> v[1:4]
<memory at 0x77ab28>
>>> v[1:4].tobytes()
'bce'

如果 memoryview 结束的对象支持更改其数据,则 memoryview 支持切片分配:

>>> data = bytearray('abcefg')
>>> v = memoryview(data)
>>> v.readonly
False
>>> v[0] = 'z'
>>> data
bytearray(b'zbcefg')
>>> v[1:4] = '123'
>>> data
bytearray(b'z123fg')
>>> v[2] = 'spam'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: cannot modify size of memoryview object

请注意如何无法更改 memoryview 对象的大小。

memoryview有两种方法:

>>> m = memoryview("abc")
>>> m.tobytes()
'abc'
>>> memoryview("abc").tolist()
[97, 98, 99]

还有一些可用的只读属性:

5.11. 上下文 Management 器类型

2.5 版的新Function。

Python 的with语句支持上下文 Management 器定义的运行时上下文的概念。这使用两种单独的方法实现,这些方法允许用户定义的类定义运行时上下文,该上下文在执行语句主体之前 Importing,在语句结束时退出。

上下文 Management 协议由Pair方法组成,它们需要为上下文 Management 器对象提供以定义运行时上下文:

返回自身的上下文 Management 器的一个示例是文件对象。文件对象从__enter __()返回自身,以允许open()用作with语句中的上下文表达式。

返回相关对象的上下文 Management 器的一个示例是decimal.localcontext()返回的对象。这些 Management 器将活动的十进制上下文设置为原始十进制上下文的副本,然后返回该副本。这允许对with语句主体中的当前十进制上下文进行更改,而不会影响with语句外部的代码。

从此方法返回 true 值将导致with语句抑制该异常,并 continue 在with语句之后立即使用该语句执行。否则,异常将在此方法执行完后 continue 传播。执行此方法期间发生的异常将替换with语句主体中发生的任何异常。

传入的异常永远不应显式引发-相反,此方法应返回 false 值,以指示该方法已成功完成并且不想抑制所引发的异常。这使上下文 Management 代码(例如contextlib.nested)可以轻松检测exit()方法是否实际上已失败。

Python 定义了多个上下文 Management 器,以支持轻松的线程同步,迅速关闭文件或其他对象以及对活动的十进制算术上下文进行更简单的操作。除了特定类型的上下文 Management 协议的实现以外,不对它们进行特殊处理。有关一些示例,请参见contextlib模块。

Python 的generatorcontextlib.contextmanager decorator提供了实现这些协议的便捷方法。如果生成器函数用contextlib.contextmanager装饰器装饰,它将返回实现必需的enter()exit()方法的上下文 Management 器,而不是由未修饰的生成器函数生成的迭代器。

请注意,在 Python/C API 中,Python 对象的类型结构中没有任何针对这些方法的特定插槽。想要定义这些方法的扩展类型必须提供它们作为普通的 Python 可访问方法。与设置运行时上下文的开销相比,单个类字典查找的开销可以忽略不计。

5.12. 其他内置类型

解释器支持其他几种对象。其中大多数仅支持一两个操作。

5.12.1. Modules

模块上唯一的特殊操作是属性访问:m.name,其中* m 是模块,而 name 访问 m 的符号表中定义的名称。可以分配模块属性。 (请注意,严格地说,import语句不是对模块对象的操作; import foo不需要存在名为 foo 的模块对象,而是需要对名为 foo 的模块进行(外部) definition *某处。)

每个模块的特殊属性是dict。这是包含模块符号表的字典。修改此字典实际上会更改模块的符号表,但是无法直接分配给dict属性(您可以编写m.__dict__['a'] = 1,它将m.a定义为1,但不能编写m.__dict__ = {})。不建议直接修改dict

解释器中内置的模块的编写方式如下:<module 'sys' (built-in)>。如果从文件加载,它们将被写为<module 'os' from '/usr/local/lib/pythonX.Y/os.pyc'>

5.12.2. 类和类实例

有关这些信息,请参见对象,值和类型Class definitions

5.12.3. Functions

Function对象由Function定义创建。对Function对象的唯一操作是调用它:func(argument-list)

函数对象实际上有两种类型:内置函数和用户定义函数。两者都支持相同的操作(以调用函数),但是实现方式不同,因此对象类型也不同。

有关更多信息,请参见Function definitions

5.12.4. Methods

方法是使用属性符号调用的函数。有两种类型:内置方法(例如列表上的append())和类实例方法。描述了内置方法及其支持的类型。

该实现向类实例方法添加了两个特殊的只读属性:m.im_self是该方法在其上操作的对象,而m.im_func是实现该方法的函数。调用m(arg-1, arg-2, ..., arg-n)完全等效于调用m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)

类实例方法是* bound unbound *,分别表示该方法是pass实例还是pass类访问的。当方法未绑定时,其im_self属性将为None,如果调用此方法,则必须将显式self对象作为第一个参数传递。在这种情况下,self必须是未绑定方法的类(或该类的子类)的实例,否则引发TypeError

像函数对象一样,方法对象也支持获取任意属性。但是,由于方法属性实际上存储在基础函数对象(meth.im_func)上,因此不允许在绑定方法或未绑定方法上设置方法属性。try在方法上设置属性会引发AttributeError。为了设置方法属性,您需要在基础函数对象上显式设置它:

>>> class C:
...     def method(self):
...         pass
...
>>> c = C()
>>> c.method.whoami = 'my name is method'  # can't set on the method
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'instancemethod' object has no attribute 'whoami'
>>> c.method.im_func.whoami = 'my name is method'
>>> c.method.whoami
'my name is method'

有关更多信息,请参见标准类型层次结构

5.12.5. 代码对象

该实现使用代码对象表示“伪编译的”可执行 Python 代码,例如函数体。它们与函数对象不同,因为它们不包含对其全局执行环境的引用。内置compile()函数返回代码对象,并且可以pass它们的func_code属性从代码对象中提取代码对象。另请参见code模块。

pass将代码对象(而不是源字符串)传递给exec语句或内置eval()函数,可以执行或评估代码对象。

有关更多信息,请参见标准类型层次结构

5.12.6. 类型对象

类型对象代表各种对象类型。内置函数type()可访问对象的类型。类型上没有特殊的操作。标准模块types为所有标准内置类型定义名称。

类型是这样写的:<type 'int'>

5.12.7. 空对象

该对象由未显式返回值的函数返回。它不支持任何特殊操作。只有一个空对象,名为None(内置名称)。

它写为None

5.12.8. Ellipsis对象

扩展的切片符号使用此对象(请参见Slicings)。它不支持任何特殊操作。恰好有一个Ellipsis号对象,名为Ellipsis(内置名称)。

它写为Ellipsis。在下标中时,也可以写为...,例如seq[...]

5.12.9. 未实现的对象

当要求它们对不支持的类型进行操作时,该对象将从比较和二进制操作返回。有关更多信息,请参见Comparisons

它写为NotImplemented

5.12.10. 布尔值

布尔值是两个常量对象FalseTrue。它们用于表示真值(尽管其他值也可以视为假或真)。在数字上下文中(例如,用作算术运算符的参数时),它们的行为分别类似于整数 0 和 1.如果该值可以解释为真值,则可以使用内置函数bool()将任何值转换为布尔值(请参见上面的真值测试部分)。

它们分别写为FalseTrue

5.12.11. 内部对象

有关此信息,请参见标准类型层次结构。它描述了堆栈框架对象,回溯对象和切片对象。

5.13. 特殊属性

该实现向与它们相关的几种对象类型添加了一些特殊的只读属性。 dir()内置函数未报告其中的一些。

new-style class es 仅支持以下属性。

>>> int.__subclasses__()
[<type 'bool'>]

Footnotes

首页