Assignment statements are used to (re)bind names to values and to modify attributes or items of mutable objects:
赋值语句用来把名字(重新)捆绑到值,以及修改可变对象的属性或者项目:
assignment_stmt |
::= | (target_list "=")+ expression_list |
target_list |
::= | target ("," target)* [","] |
target |
::= | identifier |
| "(" target_list ")" | ||
| "[" target_list "]" | ||
| attributeref | ||
| subscription | ||
| slicing |
(See section 5.3 for the syntax definitions for the last three symbols.)
(上面后三项符号的语法定义参看5.3节)
An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.
一个赋值语句对表达式序列求值 (还记得这可以是单个表达式或者一个逗号分隔的序列,后者导出一个元组),然后从左到右地将对象结果一一地赋给目的序列的每个对象。
Assignment is defined recursively depending on the form of the target (list). When a target is part of a mutable object (an attribute reference, subscription or slicing), the mutable object must ultimately perform the assignment and decide about its validity, and may raise an exception if the assignment is unacceptable. The rules observed by various types and the exceptions raised are given with the definition of the object types (see section 3.2).
依赖于目标(序列)的形式,赋值被递归地定义。当目标是一个可变对象的一部分(属性引用,下标,片断)的时候,该可变对象必须最终执行该赋值,决定其有效性,并且如果该赋值不可接受可能会抛出一个例外。不同类型以及抛出例外所遵循的规则在该对象类型的定义中给出(见3.2节)。
Assignment of an object to a target list is recursively defined as follows.
一个对象向一个目的序列的赋值递归地定义如下.
如果目标序列是单个目标,该对象就赋予该目标。
如果目标序列是一组用逗号分隔的目标:该对象必须是一个其子项个数与目标序列中的目标个数一样多的有序类型对象,且其子项,从左到右地,逐个赋予相应目标。(这个规则从Python 1.5开始放宽了;在早期版本中,对象必须是一个元组。既然字符串是有序类型对象,像"a,b = "xy""这样的赋值现在就是合法的,只要该字符串有正确的长度。
Assignment of an object to a single target is recursively defined as follows.
一个对象向单个目标的赋值递归地定义如下。
如果该目标是一个标志符(名字):
如果该名字不出现于当前代码块的global语句当中:该名字就约束到当前局部名字空间的对象上。
否则:该名字约束到当前全局名字空间中的对象。
The name is rebound if it was already bound. This may cause the reference count for the object previously bound to the name to reach zero, causing the object to be deallocated and its destructor(if it has one) to be called.
如果名字已经被约束了它就被重新约束。这可能导致早先约束到该名字的对象的引用计数降为零,导致释放该对象的分配空间并调用其析构器,如果它有一个的话。
如果目标是一个用括号或者方括号括起来的目标序列:该对象必须是具有和目标序列中目标个数同样数目的有序类型,且其子项从左到右地赋值给相应目标。
如果目标是一个属性引用:引用中的主元表达式被求值。它应该给出一个带可赋值属性的对象;如果不是这种情况,就会抛出TypeError例外。然后那个对象就被要求将被赋值的对象赋值给给定的属性;如果它无法执行该赋值,就会抛出一个例外(通常但是不必然是AttributeError异常)。
如果目标是一个下标:引用中的主元表达式被求值。这应给出或者一个可变有序对象(比如,一个列表)或者一个映射对象(比如,一个字典)。接着,下标表达式被求值。
If the primary is a mutable sequence object (e.g., a list), the subscript must yield a plain integer. If it is negative, the sequence's length is added to it. The resulting value must be a nonnegative integer less than the sequence's length, and the sequence is asked to assign the assigned object to its item with that index. If the index is out of range, IndexError is raised (assignment to a subscripted sequence cannot add new items to a list).
如果主元是可变有序对象(例如列表),下标必须给出一个普通整数。如果是负数,序列的长度就被加上。最后的值必须是一个小于该序列长度的非负整数,然后该序列就被请求将被赋对象赋值给它带那个指标的项。如果指标超出范围,就会抛出IndexError例外(给一个用下标引用的有序对象赋值不会给列表增添新项)。
If the primary is a mapping object (e.g., a dictionary), the subscript must have a type compatible with the mapping's key type, and the mapping is then asked to create a key/datum pair which maps the subscript to the assigned object. This can either replace an existing key/value pair with the same key value, or insert a new key/value pair (if no key with the same value existed).
如果主元是一个映射对象(比如字典),下标的类型必须和映射的键类型兼容,接着该映射就被要求创建一个把下标映射到被赋对象的键/数据对。这(操作)要不用新键值取代已存在的具有相同键的键/值对,要不插入一个新的键/值对(如果不存在相同的键)。
如果目标是一片断:引用中的主元表达式被求值。这应给出一个可变有序对象(比如列表)。被赋值对象应该是同一类型的有序对象。下一步,在它们所出现的范围内,对上下限表达式求值;缺省值是零和序列长度。限值应求值为(小)整数。如果任一限是负的,就加上序列的长度。结果限值被修整至零和序列长度之间(含零和序列长度)。最后,有序对象被要求用被赋有序对象的子项替换该片断。片断的长度可能和被赋序列的长度不同,那就改变目标序列的长度,如果该对象允许的话。
(In the current implementation, the syntax for targets is taken to be the same as for expressions, and invalid syntax is rejected during the code generation phase, causing less detailed error messages.)
(在当前的实现中,目标对象的语法被认为和表达式的语法相同,并且非法语法在代码生成期被拒绝,这导致缺少详细的错误信息)
WARNING: Although the definition of assignment implies that overlaps between the left-hand side and the right-hand side are `safe' (e.g., "a, b = b, a" swaps two variables), overlaps within the collection of assigned-to variables are not safe! For instance, the following program prints "[0, 2]":
警告:虽然赋值的定义隐含着左手边和右手边之间的重叠是“安全的”(比如,"a, b = b, a"交换两个变量),在所赋值变量间的重叠却是不安全的!例如,下面的程序打印出"[0, 2]":
x = [0, 1] i = 0 i, x[i] = 1, 2 print x