python基础教程之表达式
6. 表达式¶
这一章解释Python中表达式的各个组成部分的含义。
Syntax Notes: 在这一章及随后的章节中所用到的扩展BNF语法符号将用于讲述语法,而不是词法分析。当一个语法规则具有这样的形式
name ::= othername
且没有给出语义,那么这种形式的name语义与othername相同。
6.1. Arithmetic conversions¶
When a description of an arithmetic operator below uses the phrase “the numeric arguments are converted to a common type,” this means that the operator implementation for built-in types works as follows:
- 如果任意一个参数是复数,将另外一个转换成复数;
- 否则,如果任意一个参数是浮点数,则将另外一个转换为浮点数;
- otherwise, both must be integers and no conversion is necessary.
Some additional rules apply for certain operators (e.g., a string as a left argument to the ‘%’ operator). Extensions must define their own conversion behavior.
6.2. 原子¶
原子是表达式最基础的元素。最简单的原子是标识符和字面值。Forms enclosed in parentheses, brackets or braces are also categorized syntactically as atoms. 原子的语法为:
atom ::= identifier | literal | enclosure enclosure ::= parenth_form | list_display | dict_display | set_display | generator_expression | yield_atom
6.2.1. Identifiers (Names)¶
一个以原子出现的标识符是一个名称。词法定义请参看标识符和关键字小节,名称和绑定的文档请参看名称和绑定小节。
当名称绑定到一个对象上时,对该原子的求值将产生那个对象。When a name is not bound, an attempt to evaluate it raises a NameError exception.
Private name mangling: 当出现在类定义中的标识符以两个或多个下划线字符开始且不是以两个或多个下划线结束,它被认为是那个类的私有名称。在为它们生成代码之前,私有名称被转换为更长的形式。该转换在名称的前面插入类的名称,前导的下滑线被删除并插入一个单一的下划线。例如,出现在类Ham中的标识符__spam将被转换成_Ham__spam。这种转换与标识符使用的语法上下文无关。如果转换后的名称过长(超过255个字符),将可能发生与具体实现有关的截断。如果类的名称只由下划线组成,则不会转换。
6.2.2. Literals¶
Python supports string and bytes literals and various numeric literals:
literal ::= stringliteral | bytesliteral | integer | floatnumber | imagnumber
Evaluation of a literal yields an object of the given type (string, bytes, integer, floating point number, complex number) with the given value. 在浮点数和虚数(复数)情况下,可能只是近似值。详细信息参见字面值一节。
All literals correspond to immutable data types, and hence the object’s identity is less important than its value. 多次计算具有相同值的字面值(无论是程序文本中相同的出现还是不同的出现)得到的既可能是同一个对象也可能是具有相同值的不同对象。
6.2.3. Parenthesized forms¶
圆括号式是包含在圆括号中的一个可选表达式序列:
parenth_form ::= "(" [expression_list] ")"
A parenthesized expression list yields whatever that expression list yields: if the list contains at least one comma, it yields a tuple; 否则,它产生组成表达式序列的那个单一表达式。
空的圆括号对产生空的元组对象;Since tuples are immutable, the rules for literals apply (i.e., two occurrences of the empty tuple may or may not yield the same object).
注意元组不是通过圆括号而是逗号操作符形成。The exception is the empty tuple, for which parentheses are required — allowing unparenthesized “nothing” in expressions would cause ambiguities and allow common typos to pass uncaught.
6.2.4. Displays for lists, sets and dictionaries¶
For constructing a list, a set or a dictionary Python provides special syntax called “displays”, each of them in two flavors:
- 容器的内容被显式地列出,或者
- 它们通过一系列循环和过滤指令计算得到,这种方式叫做推导式。
推导式常见的语法元素为:
comprehension ::= expression comp_for comp_for ::= "for" target_list "in" or_test [comp_iter] comp_iter ::= comp_for | comp_if comp_if ::= "if" expression_nocond [comp_iter]
推导式由一个单一的表达式后面跟随至少一个for子句加上零个或多个for或者if子句。在这种情况下,新的列表的元素是由for或者if子句块产生,这些子句块从左向右嵌套,且当到达最内层的代码块时对表达式求值以产生一个列表元素。
Note that the comprehension is executed in a separate scope, so names assigned to in the target list don’t “leak” into the enclosing scope.
6.2.5. List displays¶
列表表示式是在方括号中的可以为空的一系列表达式:
list_display ::= "[" [expression_list | comprehension] "]"
A list display yields a new list object, the contents being specified by either a list of expressions or a comprehension. 当提供的是一个逗号分隔的表达式序列时,对它的元素从左向右求值并按此顺序放入列表对象中。When a comprehension is supplied, the list is constructed from the elements resulting from the comprehension.
6.2.6. Set displays¶
集合表示式通过花括号表明,与字典表示式的区别是缺少冒号分隔的键和值:
set_display ::= "{" (expression_list | comprehension) "}"
集合表示式产生一个新的可变集合对象,它的内容可以通过一个表达式序列或者一个推导式指定。当提供的是一个逗号分隔的表达式序列时,将从左向右计算它的元素并添加到集合对象中。当提供的是一个推导式时,集合根据推导式产生的元素构造。
不可以用{}构造一个空集合;该字面值构造一个空的字典。
6.2.7. Dictionary displays¶
字典表示式是在花括号中的可以为空的一系列键/值对。
dict_display ::= "{" [key_datum_list | dict_comprehension] "}" key_datum_list ::= key_datum ("," key_datum)* [","] key_datum ::= expression ":" expression dict_comprehension ::= expression ":" expression comp_for
字典表示式产生一个新的字典对象。
如果给出逗号分隔的键/值对序列,将从左向右对它们求值以定义字典中项:用每个键对象作为字典的键并存储对应的值。这意味着你可以在键/值序列中多次指定相同的键,但是该键最终对应的字典的值将是最后给出的那个值。
字典推导式,与列表和集合推导式相比,需要两个被冒号分隔的表达式并在后面跟随通常的“for”和“if”子句。当推导执行时,产生的键和值以它们生成的顺序插入到新的字典中。
键的类型的限制在前面的标准类型的层次一节中有列出。(简要地讲,键的类型应该是可哈希的,即排除所有可变的对象。)重复的键之间的冲突不会被检测到;一个给定的键的最后的值(表示式中最右边的值)将获胜。
6.2.8. Generator expressions¶
生成器表达式是在圆括号中的一个简洁的生成器符号:
generator_expression ::= "(" expression comp_for ")"
生成器表达式产生一个新的生成器对象。它的语法与推导式相同,只是它位于圆括号而不是方括号或花括号中。
Variables used in the generator expression are evaluated lazily when the __next__() method is called for the generator object (in the same fashion as normal generators). 但是,最左边的for子句会立即计算,所以它产生的错误可以在生成器表达式代码中的任何其它可能的错误之前发现。随后的for子句不可以立即计算因为它们可能依赖于前面的for循环。例如:(x*y for x in range(10) for y in bar(x))。
圆括号对于只有一个参数的调用可以省略。See section Calls for details.
6.2.9. Yield expressions¶
yield_atom ::= "(" yield_expression ")" yield_expression ::= "yield" [expression_list | "from" expression]
The yield expression is only used when defining a generator function and thus can only be used in the body of a function definition. Using a yield expression in a function’s body causes that function to be a generator.
当调用生成器函数时,它返回一个称为生成器的迭代器。That generator then controls the execution of the generator function. 当调用生成器的其中一个方法时,执行开始。At that time, the execution proceeds to the first yield expression, where it is suspended again, returning the value of expression_list to the generator’s caller. By suspended, we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, the internal evaluation stack, and the state of any exception handling. When the execution is resumed by calling one of the generator’s methods, the function can proceed exactly as if the yield expression were just another external call. The value of the yield expression after resuming depends on the method which resumed the execution. If __next__() is used (typically via either a for or the next() builtin) then the result is None. Otherwise, if send() is used, then the result will be the value passed in to that method.
所有这些使得生成器函数与协程非常类似;它们可以yield多次,它们有多个入口点且它们的执行可以挂起。The only difference is that a generator function cannot control where the execution should continue after it yields; 控制始终被转让给生成器的调用者。
Yield expressions are allowed anywhere in a try construct. If the generator is not resumed before it is finalized (by reaching a zero reference count or by being garbage collected), the generator-iterator’s close() method will be called, allowing any pending finally clauses to execute.
When yield from <expr> is used, it treats the supplied expression as a subiterator. All values produced by that subiterator are passed directly to the caller of the current generator’s methods. Any values passed in with send() and any exceptions passed in with throw() are passed to the underlying iterator if it has the appropriate methods. If this is not the case, then send() will raise AttributeError or TypeError, while throw() will just raise the passed in exception immediately.
When the underlying iterator is complete, the value attribute of the raised StopIteration instance becomes the value of the yield expression. It can be either set explicitly when raising StopIteration, or automatically when the sub-iterator is a generator (by returning a value from the sub-generator).
Changed in version 3.3: Added yield from <expr> to delegate control flow to a subiterator
The parentheses may be omitted when the yield expression is the sole expression on the right hand side of an assignment statement.
请参阅
- PEP 0255 – Simple Generators
- The proposal for adding generators and the yield statement to Python.
- PEP 0342 – Coroutines via Enhanced Generators
- 增强生成器API和语法的提议,使得它们可以作为简单的协程使用。
- PEP 0380 – Syntax for Delegating to a Subgenerator
- The proposal to introduce the yield_from syntax, making delegation to sub-generators easy.
6.2.9.1. Generator-iterator methods¶
该小节讲述生成器迭代器的方法。它们可用于控制生成器函数的执行。
Note that calling any of the generator methods below when the generator is already executing raises a ValueError exception.
- generator.__next__()¶
-
Starts the execution of a generator function or resumes it at the last executed yield expression. When a generator function is resumed with a __next__() method, the current yield expression always evaluates to None. The execution then continues to the next yield expression, where the generator is suspended again, and the value of the expression_list is returned to __next__()‘s caller. If the generator exits without yielding another value, a StopIteration exception is raised.
This method is normally called implicitly, e.g. by a for loop, or by the built-in next() function.
- generator. send(value)¶
-
恢复执行并“发送”一个值到生成器中。The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value.
- generator.throw(type[, value[, traceback]])¶
-
Raises an exception of type type at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a StopIteration exception is raised. 如果生成器函数没有捕获传递进来的异常或者引发一个不同的异常,那么该异常将传播到调用者。
- generator.close()¶
-
Raises a GeneratorExit at the point where the generator function was paused. If the generator function then raises StopIteration (by exiting normally, or due to already being closed) or GeneratorExit (by not catching the exception), close returns to its caller. If the generator yields a value, a RuntimeError is raised. 如果生成器引发其它任何异常,它会被传播到调用者。如果生成器已经由于异常退出或正常退出,close()不会做任何事情。
6.2.9.2. Examples¶
这里有个简单的例子演示生成器和生成器函数的行为:
>>> def echo(value=None):
... print("Execution starts when 'next()' is called for the first time.")
... try:
... while True:
... try:
... value = (yield value)
... except Exception as e:
... value = e
... finally:
... print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> print(next(generator))
Execution starts when 'next()' is called for the first time.
1
>>> print(next(generator))
None
>>> print(generator.send(2))
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.
For examples using yield from, see PEP 380: Syntax for Delegating to a Subgenerator in “What’s New in Python.”
6.3. Primaries¶
初级操作表示语言中绑定性最高的操作。它们的语法是:
primary ::= atom | attributeref | subscription | slicing | call
6.3.1. Attribute references¶
属性引用是一个初级操作,后面跟随一个句号和一个名称:
attributeref ::= primary "." identifier
The primary must evaluate to an object of a type that supports attribute references, which most objects do. 接着该对象被要求生成名称为identifier的属性。This production can be customized by overriding the __getattr__() method. If this attribute is not available, the exception AttributeError is raised. 否则,生成的对象的类型和值取决于该对象。对相同属性的多次求值可能产生不同的对象。
6.3.2. Subscriptions¶
下标选择序列(字符串、元组或列表)或者映射(字典)对象的一个元素:
subscription ::= primary "[" expression_list "]"
The primary must evaluate to an object that supports subscription (lists or dictionaries for example). User-defined objects can support subscription by defining a __getitem__() method.
For built-in objects, there are two types of objects that support subscription:
如果primary是一个映射,那么expression_list必须是一个对象,其值为映射的一个键,该下标选择映射中对应于该键的值。(expression_list是一个元组除非它只有一个元素。)
If the primary is a sequence, the expression (list) must evaluate to an integer or a slice (as discussed in the following section).
The formal syntax makes no special provision for negative indices in sequences; however, built-in sequences all provide a __getitem__() method that interprets negative indices by adding the length of the sequence to the index (so that x[-1] selects the last item of x). 结果值必须是一个小于序列元素个数的非负整数,下标操作选择索引为该值的元素(从零开始计数)。Since the support for negative indices and slicing occurs in the object’s __getitem__() method, subclasses overriding this method will need to explicitly add that support.
字符串的元素为字符。字符不是一个单独的数据类型而是只有一个字符的字符串。
6.3.3. Slicings¶
切片选择序列对象(例如,字符串、元组和列表)中一个范围内的元素。切片可以用作表达式或者作为赋值和del语句的目标。切片的语法:
slicing ::= primary "[" slice_list "]" slice_list ::= slice_item ("," slice_item)* [","] slice_item ::= expression | proper_slice proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ] lower_bound ::= expression upper_bound ::= expression stride ::= expression
这里的形式语法有歧义:expession_list看上去也像slice_list,所以任何下标也可以解释为切片。Rather than further complicating the syntax, this is disambiguated by defining that in this case the interpretation as a subscription takes priority over the interpretation as a slicing (this is the case if the slice list contains no proper slice).
The semantics for a slicing are as follows. The primary is indexed (using the same __getitem__() method as normal subscription) with a key that is constructed from the slice list, as follows. 如果slice_list包含至少一个逗号,则键是一个包含slice_item转换的元组;否则,long_slice作为键。slice_item是一个表达式时,转换就是那个表达式。The conversion of a proper slice is a slice object (see section The standard type hierarchy) whose start, stop and step attributes are the values of the expressions given as lower bound, upper bound and stride, respectively, substituting None for missing expressions.
6.3.4. Calls¶
调用是指用一个可以为空的参数序列调用一个可调用对象(例如,一个函数):
call ::= primary "(" [argument_list [","] | comprehension] ")" argument_list ::= positional_arguments ["," keyword_arguments] ["," "*" expression] ["," keyword_arguments] ["," "**" expression] | keyword_arguments ["," "*" expression] ["," keyword_arguments] ["," "**" expression] | "*" expression ["," keyword_arguments] ["," "**" expression] | "**" expression positional_arguments ::= expression ("," expression)* keyword_arguments ::= keyword_item ("," keyword_item)* keyword_item ::= identifier "=" expression
An optional trailing comma may be present after the positional and keyword arguments but does not affect the semantics.
The primary must evaluate to a callable object (user-defined functions, built-in functions, methods of built-in objects, class objects, methods of class instances, and all objects having a __call__() method are callable). 所有的参数表达式都将在调用发生之前求值。关于形式参数列表的语法请参考函数的定义一节。
如果存在关键字参数,它们首先被转换为位置参数,如下所述。首先,创建一个没有填充的空位序列用于形参。如果有N个位置参数,则它们被放置在前N个空位中。下一步,对于每个关键字参数,用标识符决定对应的位置(如果标识符与第一个形参的名称相同,则使用第一个位置,以此类推)。If the slot is already filled, a TypeError exception is raised. Otherwise, the value of the argument is placed in the slot, filling it (even if the expression is None, it fills the slot). 当处理完所有的参数时,仍然没有填充的位置将用来自函数定义的对应默认值填充。(默认值只在函数定义时计算一次;因此,用于默认值的可变对象例如列表或字典将被所有没有指定对应位置参数值的调用共享;通常应该避免这点。)If there are any unfilled slots for which no default value is specified, a TypeError exception is raised. 否则,使用这些填满的位置作为调用的参数序列。
CPython实现细节: 一种实现可以提供这样的内建函数,它的位置参数没有名称,因此不可以通过关键字提供,即使它们由于文档的需要而被“命名”。In CPython, this is the case for functions implemented in C that use PyArg_ParseTuple() to parse their arguments.
If there are more positional arguments than there are formal parameter slots, a TypeError exception is raised, unless a formal parameter using the syntax *identifier is present; 在这种情况下,该形参接收一个包含多余位置参数的元组(如果没有多余的位置参数则为空元组)。
If any keyword argument does not correspond to a formal parameter name, a TypeError exception is raised, unless a formal parameter using the syntax **identifier is present; 在这种情况下,该形参接收一个包含多余的关键字参数的字典(使用关键字作为键,参数值作为对应的值),如果没有多余的关键字参数则为一个(新的)空字典。
如果*expression语法出现在函数调用中,那么expression必须是一个可迭代器。来自该可迭代器的元素被当作额外的位置参数;如果位置参数为x1, …, xN且expression求值为一个序列y1, …, yM,那么它等同于用M+N个位置参数x1, …, xN, y1, …, yM的调用。
这种方式的后果是虽然*expression可以出现在某些关键字参数之后,但是它将在关键字参数(以及**expression参数–见下文)之前处理。所以:
>>> def f(a, b):
... print(a, b)
...
>>> f(b=1, *(2,))
2 1
>>> f(a=1, *(2,))
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: f() got multiple values for keyword argument 'a'
>>> f(1, *(2,))
1 2
关键字参数和*expression语法都在同一个调用中使用很不常见,所以实践中这种困惑不会出现。
如果**expression语法出现在函数调用中,那么expression必须是一个映射,它的内容将被当作额外的关键字参数。In the case of a keyword appearing in both expression and as an explicit keyword argument, a TypeError exception is raised.
使用*identifier或者**identifier语法的形参不可以作为位置参数的槽位或者关键字参数的名称使用。
A call always returns some value, possibly None, unless it raises an exception. 该值如何计算取决于可调用对象的类型。
如果它是—
- 一个用户定义的函数:
-
该函数的代码块将被执行,并将参数列表传递给它。代码块所做的第一件事是将绑实参与参数定;这在函数的定义一节有讲述。当代码块执行一条return时,它表示该函数调用的返回值。
- 一个内建的函数或方法:
-
结果取决于解释器;内建函数和方法的描述请参见内建的函数 。
- 一个类对象:
-
返回该类的一个新的实例。
- 一个类实例的方法:
-
调用对应的用户自定义的函数,参数列表比调用的参数列表多一个元素:实例成为第一个参数。
- 一个类实例:
-
该类必须定义一个__call__()方法;效果和调用该方法一样。
6.4. The power operator¶
乘方操作符的绑定性比它左侧的一元操作符高;比它右侧的一元操作符绑定性低。其语法是:
power ::= primary ["**" u_expr]
因此,在一个没有括号的乘方和一元操作符序列中,操作符从右向左计算(这不会约束操作数的计算顺序):-1**2的结果是-1。
乘方操作符的语义与用两个参数调用内建的pow()函数相同:它产生左侧参数的右侧参数次幂。The numeric arguments are first converted to a common type, and the result is of that type.
For int operands, the result has the same type as the operands unless the second argument is negative; 在这种情况下, 所有的参数都会被转化成浮点型,并且会返回一个浮点的结果。例如, 10**2 返回 100, 但 10**-2 返回0.01.
Raising 0.0 to a negative power results in a ZeroDivisionError. Raising a negative number to a fractional power results in a complex number. (In earlier versions it raised a ValueError.)
6.5. Unary arithmetic and bitwise operations¶
所有的一元算术和位操作具有相同的优先级:
u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr
一元-(负)操作符产生其数值参数的负值。
一元+(正)操作符产生其数值参数保持不变。
The unary ~ (invert) operator yields the bitwise inversion of its integer argument. x按位取反定义为-(x+1)。它只适用于整数数值。
In all three cases, if the argument does not have the proper type, a TypeError exception is raised.
6.6. Binary arithmetic operations¶
二元算术操作具有传统的优先级。注意这里的某些操作同样适用于一些非数值类型。除了乘方操作符,有两个优先级,一个针对乘法操作符,一个针对加法操作符:
m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr | m_expr "%" u_expr a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr
*(乘法)操作符产生它参数的乘积。The arguments must either both be numbers, or one argument must be an integer and the other must be a sequence. 在前一种情况下,数值会被转换成一个相同的类型然后一起相乘。在后一种情况下,将进行序列的重复操作;负的重复值将产生一个空的序列。
/(除法)和//(整除)操作符产生它们参数的商。其数值参数首先被转换成相同的类型。Division of integers yields a float, while floor division of integers results in an integer; 其结果是在算术除法的结果上调用“取整”函数。Division by zero raises the ZeroDivisionError exception.
%(取模)操作符产生第一个参数除以第二个参数后的余数。其数值参数首先被转换成相同的类型。A zero right argument raises the ZeroDivisionError exception. 参数可以是浮点数,例如,3.14%0.7等于0.34(因为3.14等于4*0.7 + 0.34。)取模操作符永远产生与第二个操作符符号相同的结果(或者为零);the absolute value of the result is strictly smaller than the absolute value of the second operand [1].
The floor division and modulo operators are connected by the following identity: x == (x//y)*y + (x%y). Floor division and modulo are also connected with the built-in function divmod(): divmod(x, y) == (x//y, x%y). [2].
In addition to performing the modulo operation on numbers, the % operator is also overloaded by string objects to perform old-style string formatting (also known as interpolation). The syntax for string formatting is described in the Python Library Reference, section printf-style String Formatting.
The floor division operator, the modulo operator, and the divmod() function are not defined for complex numbers. 作为替代,如果合适,使用将abs()函数将其转换为浮点数。
+(加法)操作符产生其参数的和。The arguments must either both be numbers or both be sequences of the same type. 在前一种情况下,数值被转换成相同的类型然后一起相加。在后一种情况下,序列被连接在一起。
-(减法)操作符产生其参数差。其数值参数首先被转换成相同的类型。
6.7. Shifting operations¶
移位操作的优先级低于算术操作:
shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr
These operators accept integers as arguments. 它们将第一个参数向左或向右移动第二个参数指出的位数。
A right shift by n bits is defined as floor division by pow(2,n). A left shift by n bits is defined as multiplication with pow(2,n).
注意
在当前的实现中,要求右操作数至多为sys.maxsize。If the right-hand operand is larger than sys.maxsize an OverflowError exception is raised.
6.8. Binary bitwise operations¶
下面三种位操作具有各自不同的优先级:
and_expr ::= shift_expr | and_expr "&" shift_expr xor_expr ::= and_expr | xor_expr "^" and_expr or_expr ::= xor_expr | or_expr "|" xor_expr
The & operator yields the bitwise AND of its arguments, which must be integers.
The ^ operator yields the bitwise XOR (exclusive OR) of its arguments, which must be integers.
The | operator yields the bitwise (inclusive) OR of its arguments, which must be integers.
6.9. Comparisons¶
与C不同,Python中所有的比较操作具有相同的优先级,并低于任何算术、移位和位操作。与C不同的还有,类似a < b < c 这样的表达式就是数学中传统的含义。
comparison ::= or_expr ( comp_operator or_expr )* comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!=" | "is" ["not"] | ["not"] "in"
Comparisons yield boolean values: True or False.
比较操作可以任意连接,例如x < y <= z等同于x < y and y <= z,但是y只计算一次(在两种情况中当发现x < y为假时都不会再计算z)。
Formally, if a, b, c, …, y, z are expressions and op1, op2, …, opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.
注意a op1 b op2 c并不意味着a 和c 之间会有比较,所以x < y > z 是完全合法的(尽管不漂亮)。
操作符<、>、==、>=、<=和!= 比较两个对象的值。对象不需要具有相同的类型。如果两个都是数字,它们将被转会成一个共同的类型。Otherwise, the == and != operators always consider objects of different types to be unequal, while the <, >, >= and <= operators raise a TypeError when comparing objects of different types that do not implement these operators for the given pair of types. You can control comparison behavior of objects of non-built-in types by defining rich comparison methods like __gt__(), described in section Basic customization.
相同类型对象的比较取决于它们的类型:
-
数字按照算术意义比较。
-
The values float('NaN') and Decimal('NaN') are special. They are identical to themselves, x is x but are not equal to themselves, x != x. Additionally, comparing any value to a not-a-number value will return False. For example, both 3 < float('NaN') and float('NaN') < 3 will return False.
-
Bytes objects are compared lexicographically using the numeric values of their elements.
-
字符串使用字符对应的数值(内建函数ord()的结果)按字典序比较。[3] String and bytes object can’t be compared!
-
元组和列表通过比较对应的项按字典序比较。 这意味着若要比较结果相等,每一个元素比较的结果必须相等且两个序列的类型必须相同并且具有相同的长度。
如果不相等,序列按照它们第一个不同的元素排序。For example, [1,2,x] <= [1,2,y] has the same value as x <= y. 如果对应的元素不存在,则长度较短的序列排在第一个(例如[1,2] < [1,2,3])。
-
Mappings (dictionaries) compare equal if and only if they have the same (key, value) pairs. Order comparisons ('<', '<=', '>=', '>') raise TypeError.
-
Sets and frozensets define comparison operators to mean subset and superset tests. Those relations do not define total orderings (the two sets {1,2} and {2,3} are not equal, nor subsets of one another, nor supersets of one another). Accordingly, sets are not appropriate arguments for functions which depend on total ordering. For example, min(), max(), and sorted() produce undefined results given a list of sets as inputs.
-
其它大部分内建类型的对象是不相等的除非它们是相同的对象;一个对象是小于还是大于另外一个对象的抉择虽然是随机的但是在程序的一次执行中是一致的。
Comparison of objects of differing types depends on whether either of the types provide explicit support for the comparison. Most numeric types can be compared with one another. When cross-type comparison is not supported, the comparison method returns NotImplemented.
The operators in and not in test for membership. x in s evaluates to true if x is a member of s, and false otherwise. x not in s返回x in s的否定式。All built-in sequences and set types support this as well as dictionary, for which in tests whether the dictionary has a given key. For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y).
For the string and bytes types, x in y is true if and only if x is a substring of y. An equivalent test is y.find(x) != -1. Empty strings are always considered to be a substring of any other string, so "" in "abc" will return True.
对于定义了__contains__()方法的用户自定义类,x in y为真当且仅当y.__contains__(x)为真。
对于没有定义__contains__()但定义__iter__()的用户自定义类,x in y为真如果某个值z在迭代y时满足x == z。 如果迭代过程中抛出异常,就好像是in抛出那个异常一样。
Lastly, the old-style iteration protocol is tried: if a class defines __getitem__(), x in y is true if and only if there is a non-negative integer index i such that x == y[i], and all lower integer indices do not raise IndexError exception. (如果引发了其它异常,则像是in引发了该异常)。
is 和is not操作测试对象的ID:x is y当且仅当x和y是相同的对象时为真。x is not y产生相反的真值。[4]
6.10. Boolean operations¶
or_test ::= and_test | or_test "or" and_test and_test ::= not_test | and_test "and" not_test not_test ::= comparison | "not" not_test
在布尔运算以及控制语句(if,while判断)中, 一下值被认为是 false: False, None, 所有算数类型的0值, 以及空的字符串和容器 (包括strings, tuples, lists, dictionaries, sets and frozensets). 其他值均为true. 自定义对象可以通过实现 __bool__() 方法来设置真值。
The operator not yields True if its argument is false, False otherwise.
表达式x and y首先计算x;如果x为假,则返回它的值;否则,再计算y 并返回结果的值。
表达式x or y首先计算x;如果x为真,则返回它的值;否则,再计算y 并返回结果的值。
(Note that neither and nor or restrict the value and type they return to False and True, but rather return the last evaluated argument. 这在有些时候是有用的,例如,如果s是一个字符串,当它是空的时候应该被一个默认值替换,那么表达式s or 'foo'就可以产生想要的值。Because not has to create a new value, it returns a boolean value regardless of the type of its argument (for example, not 'foo' produces False rather than ''.)
6.11. Conditional expressions¶
conditional_expression ::= or_test ["if" or_test "else" expression] expression ::= conditional_expression | lambda_expr expression_nocond ::= or_test | lambda_expr_nocond
条件表达式(有时叫做“三元操作符”)在所有的Python操作符中具有最低的优先级。
The expression x if C else y first evaluates the condition, C rather than x. 如果C为真,则计算x 并返回它的值;否则,计算y 并返回它的值。
See PEP 308 for more details about conditional expressions.
6.12. Lambdas¶
lambda_expr ::= "lambda" [parameter_list]: expression lambda_expr_nocond ::= "lambda" [parameter_list]: expression_nocond
Lambda expressions (有时被称作 lambda forms),被用于创建匿名函数。表达式lambda arguments: expression生成一个函数对象。此命名对象的行为类似下面定义的函数对象
def <lambda>(arguments):
return expression
关于参数列表的语法,请参见函数定义一节。Note that functions created with lambda expressions cannot contain statements or annotations.
6.13. Expression lists¶
expression_list ::= expression ( "," expression )* [","]
至少包含一个逗号的表达式序列产生一个元组。元组的长度是列表中表达式的个数。表达式按从左到右的顺序计算。
尾部的逗号仅仅在创建单元素元组(又叫独元)时需要;在其它所有情况下,它都是可选的。尾部没有逗号的表达式不会创建元组,而是产生该表达式的值。(如果要创建一个空的元组,请使用一对空的圆括号:()。)
6.14. Evaluation order¶
Python从左向右计算表达式。注意在计算赋值语句时,右侧的表达式在左侧之前计算。
在下面的每一行中,表达式按照它们后缀数字的顺序计算:
expr1, expr2, expr3, expr4
(expr1, expr2, expr3, expr4)
{expr1: expr2, expr3: expr4}
expr1 + expr2 * (expr3 - expr4)
expr1(expr2, expr3, *expr4, **expr5)
expr3, expr4 = expr1, expr2
6.15. Operator precedence¶
The following table summarizes the operator precedence in Python, from lowest precedence (least binding) to highest precedence (most binding). 在相同单元格中的操作符具有相同的优先级。除非给出明确的语法,否则操作符是二元的。Operators in the same box group left to right (except for exponentiation, which groups from right to left).
Note that comparisons, membership tests, and identity tests, all have the same precedence and have a left-to-right chaining feature as described in the Comparisons section.
操作符 | 描述 |
---|---|
lambda | Lambda 表达式 |
if – else | 条件表达式 |
or | 布尔或 |
and | 布尔与 |
not x | 布尔非 |
in, not in, is, is not, <, <=, >, >=, !=, == |
比较,包括成员测试和身份测试 |
| | 按位的或 |
^ | 按位的异或 |
& | 按位的与 |
<<, >> | 移位 |
+, - | 加法和减法 |
*, /, //, % | 乘法、除法、取余[5] |
+x, -x, ~x | 正数、负数、按位取反 |
** | 幂[6] |
x[index], x[index:index], x(arguments...), x.attribute |
下标、切片、调用、属性引用 |
(expressions...), [expressions...], {key: value...}, {expressions...} |
Binding or tuple display, list display, dictionary display, set display |
脚注
[1] | 虽然abs(x%y) < abs(y)在数学上为真,但是由于数字的舍入它对于浮点数可能不为真。For example, and assuming a platform on which a Python float is an IEEE 754 double-precision number, in order that -1e-100 % 1e100 have the same sign as 1e100, the computed result is -1e-100 + 1e100, which is numerically exactly equal to 1e100. 函数math.fmod()返回的结果的符号与第一个参数相匹配,所以在这种情况下返回-1e-100。哪种方式更合适取决于应用程序。 |
[2] | If x is very close to an exact integer multiple of y, it’s possible for x//y to be one larger than (x-x%y)//y due to rounding. 在这些情况下,Python返回后一种结果,以保持divmod(x,y)[0] * y + x % y与x非常接近。 |
[3] | While comparisons between strings make sense at the byte level, they may be counter-intuitive to users. For example, the strings "\u00C7" and "\u0327\u0043" compare differently, even though they both represent the same unicode character (LATIN CAPITAL LETTER C WITH CEDILLA).To compare strings in a human recognizable way, compare using unicodedata.normalize(). |
[4] | 由于自动垃圾回收、自由列表以及描述器的动态特性,你可能注意到is操作符在某些使用中的不太寻常的行为,比如实例的方法或常数之间的比较。查看它们的文档以获得更多信息。 |
[5] | The % operator is also used for string formatting; the same precedence applies. |
[6] | The power operator ** binds less tightly than an arithmetic or bitwise unary operator on its right, that is, 2**-1 is 0.5. |