7. 复合语句

复合语句包含(多组))其它语句;它们以某种方式影响或者控制其它那些语句的执行。通常,复合语句跨越多行,虽然一条完整的复合语句可以用简洁的形式包含在一行之中。

ifwhilefor语句实现传统的控制流句法结构。try指出一组语句的异常处理器和/或清理代码。函数和类定义在语法上同样也是复合语句。

复合语句由一个或多个‘子句’组成。一条子句由语句首和‘语句组’组成。一条特定的复合语句的所有子句的语句首都处在相同的缩进水平上。每一个子句的语句首以一个唯一的标识关键字开始并以冒号结束。语句组是由一条子句控制的一组语句。一个语句组可以是语句首冒号之后的同一行上紧跟一个或多个分号分隔的简单语句,也可以是后续行上一个或多个缩进的语句。只有后一种形式的语句组可以包含嵌套的复合语句;下面的语句是非法的,最主要是因为不能明确随后的else子句属于哪一个if子句:

if test1: if test2: print x

同时要注意在该上下文中分号的优先级比冒号高, 所以在下面的例子中,要么执行所有的print语句,要么都不执行:

if x < y < z: print x; print y; print z

总结:

compound_stmt ::=  if_stmt
                   | while_stmt
                   | for_stmt
                   | try_stmt
                   | with_stmt
                   | funcdef
                   | classdef
                   | decorated
suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]

注意语句永远以NEWLINE结束,其后可能跟随一个DEDENTAlso note that optional continuation clauses always begin with a keyword that cannot start a statement, thus there are no ambiguities (the ‘dangling else‘ problem is solved in Python by requiring nested if statements to be indented).

为了清晰起见,下面小节中的语法规则的格式会将子句放在单独的一行。

7.1. if 语句

if 语句用于条件执行:

if_stmt ::=  "if" expression ":" suite
             ( "elif" expression ":" suite )*
             ["else" ":" suite]

它通过对表达式逐个求值直到其中一个为真的方式准确地选择一个语句组(真和假的定义参见布尔操作 一节);然后执行这个语句组(if语句的其它部分不会被执行或求值)。如果所有表达式都为假,则执行else子句的语句组。

7.2. The while statement

while语句用于重复执行只要表达式为真:

while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

This repeatedly tests the expression and, if it is true, executes the first suite; 如果表达式为假(可能是第一次测试),则执行else子句的suite(如果存在)并终止循环。

A break statement executed in the first suite terminates the loop without executing the else clause’s suite. A continue statement executed in the first suite skips the rest of the suite and goes back to testing the expression.

7.3. The for statement

The for statement is used to iterate over the elements of a sequence (such as a string, tuple or list) or other iterable object:

for_stmt ::=  "for" target_list "in" expression_list ":" suite
              ["else" ":" suite]

The expression list is evaluated once; it should yield an iterable object. An iterator is created for the result of the expression_list. The suite is then executed once for each item provided by the iterator, in the order of ascending indices. Each item in turn is assigned to the target list using the standard rules for assignments, and then the suite is executed. When the items are exhausted (which is immediately when the sequence is empty), the suite in the else clause, if present, is executed, and the loop terminates.

A break statement executed in the first suite terminates the loop without executing the else clause’s suite. A continue statement executed in the first suite skips the rest of the suite and continues with the next item, or with the else clause if there was no next item.

The suite may assign to the variable(s) in the target list; this does not affect the next item assigned to it.

The target list is not deleted when the loop is finished, but if the sequence is empty, it will not have been assigned to at all by the loop. Hint: the built-in function range() returns a sequence of integers suitable to emulate the effect of Pascal’s for i := a to b do; e.g., range(3) returns the list [0, 1, 2].

Note

There is a subtlety when the sequence is being modified by the loop (this can only occur for mutable sequences, i.e. lists). An internal counter is used to keep track of which item is used next, and this is incremented on each iteration. When this counter has reached the length of the sequence the loop terminates. This means that if the suite deletes the current (or a previous) item from the sequence, the next item will be skipped (since it gets the index of the current item which has already been treated). Likewise, if the suite inserts an item in the sequence before the current item, the current item will be treated again the next time through the loop. This can lead to nasty bugs that can be avoided by making a temporary copy using a slice of the whole sequence, e.g.,

for x in a[:]:
    if x < 0: a.remove(x)

7.4. The try statement

try语句为一组语句指定异常处理器和/或清理代码:

try_stmt  ::=  try1_stmt | try2_stmt
try1_stmt ::=  "try" ":" suite
               ("except" [expression [("as" | ",") target]] ":" suite)+
               ["else" ":" suite]
               ["finally" ":" suite]
try2_stmt ::=  "try" ":" suite
               "finally" ":" suite

Changed in version 2.5: In previous versions of Python, try...except...finally did not work.try...except had to be nested in try...finally.except had to be nested in try...finally.

except子句指定一个或多个异常处理器.。try子句中没有出现异常时,不会执行异常处理器。When an exception occurs in the try suite, a search for an exception handler is started. This search inspects the except clauses in turn until one is found that matches the exception. An expression-less except clause, if present, must be last; it matches any exception. For an except clause with an expression, that expression is evaluated, and the clause matches the exception if the resulting object is “compatible” with the exception. An object is compatible with an exception if it is the class or a base class of the exception object, or a tuple containing an item compatible with the exception.

如果没有except子句匹配到异常,异常处理器的搜索将继续在外层代码和调用栈上进行。 [1]

如果计算except子句头部的一个表达式引发了异常, 那么就会中断原异常处理器的搜索, 而在外层代码和调用栈上搜索新的异常处理器(就好像是整个try语句发生了异常一样)。

When a matching except clause is found, the exception is assigned to the target specified in that except clause, if present, and the except clause’s suite is executed. All except clauses must have an executable block. When the end of this block is reached, execution continues normally after the entire try statement. (This means that if two nested handlers exist for the same exception, and the exception occurs in the try clause of the inner handler, the outer handler will not handle the exception.)

在执行except子句的语句组之前,异常的详细信息被赋值给sys模块中的三个变量:sys.exc_type接收标识异常的对象;sys.exc_value接收异常的参数;sys.exc_traceback接收一个回溯对象(参见标准类型的层级一节)指示程序中异常发生的点。这些详细信息也可以通过sys.exc_info()函数得到,它返回一个元组(exc_type, exc_value, exc_traceback)Use of the corresponding variables is deprecated in favor of this function, since their use is unsafe in a threaded program. 从Python 1.5 开始,这些值会在处理异常的函数返回时会恢复它们之前的值(调用之前的值)。

The optional else clause is executed if and when control flows off the end of the try clause. [2]else子句中的异常不会被前面的except子句处理。

如果有finally出现,它指定一个“清除”处理器。首先执行try子句被执行,然后包括任何exceptelse子句。If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. 最后执行finally子句。如果有保存的异常,它会在finally子句结束时被重新抛出。如果finally抛出另外一个异常或者执行一个returnbreak语句,那么保存的异常会被丢弃:

>>> def f():
...     try:
...         1/0
...     finally:
...         return 42
...
>>> f()
42

finally子句执行过程中程序访问不到异常信息。

returnbreakcontinue语句在try...finally语句的try语句组中被执行,finally子句在‘出口’处同样被执行。continue语句出现在finally子句中是非法的。(The reason is a problem with the current implementation — this restriction may be lifted in the future).

函数的返回值取决于执行的最后一条return语句。因为finally子句会永远执行,在finally子句中执行的return语句将永远是最后执行的一条语句:

>>> def foo():
...     try:
...         return 'try'
...     finally:
...         return 'finally'
...
>>> foo()
'finally'

额外的信息可以在异常一节中找到,关于如何使用raise语句产生异常可以在raise语句一节中找到。

7.5. The with statement

New in version 2.5.

with用于和上下文管理器定义的方法一起封装代码块的执行(参见With语句的上下文管理器一节)。这允许把常见的try...except...finally的用法模式封装起来以方便地重用。

with_stmt ::=  "with" with_item ("," with_item)* ":" suite
with_item ::=  expression ["as" target]

带有一个“item”的with语句的执行按下面的方式进行:

  1. The context expression (the expression given in the with_item) is evaluated to obtain a context manager.

  2. 加载上下文管理器的__exit__()方法留着后面使用。

  3. 调用上下文管理器的__enter__()方法。

  4. 如果with语句包含一个目标,__enter__()的返回值将赋值给它。

    Note

    with语句保证如果__enter__()方法没有错误返回,那么__exit__()将总是会被调用。Thus, if an error occurs during the assignment to the target list, it will be treated the same as an error occurring within the suite would be. See step 6 below.

  5. The suite is executed.

  6. 调用上下文管理器的__exit__()方法。If an exception caused the suite to be exited, its type, value, and traceback are passed as arguments to __exit__(). Otherwise, three None arguments are supplied.

    如果语句组由于异常退出,且__exit__()方法的返回值为假,异常将被重新引发。如果返回值为真,异常将被取消,并继续执行with语句之后的语句。

    如果语句组由于异常以外的其它任何原因退出,__exit__()的返回值将被忽略,执行将在退出发生的正常位置继续。

如果有多个条目,上下文管理器的处理如同嵌套的多个with语句:

with A() as a, B() as b:
    suite

is equivalent to

with A() as a:
    with B() as b:
        suite

Note

在Python 2.5中,with只有在with_statement特性被启用的时候才允许使用。在Python 2.6中,它默认地总是会启用。

Changed in version 2.7: Support for multiple context expressions.

另请参阅

PEP 0343 - “with”语句
Python with语句的说明、背景和实例。

7.6. Function definitions

函数定义定义一个用户自定义的函数对象(参见标准类型的层次一节):

decorated      ::=  decorators (classdef | funcdef)
decorators     ::=  decorator+
decorator      ::=  "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
funcdef        ::=  "def" funcname "(" [parameter_list] ")" ":" suite
dotted_name    ::=  identifier ("." identifier)*
parameter_list ::=  (defparameter ",")*
                    (  "*" identifier ["," "**" identifier]
                    | "**" identifier
                    | defparameter [","] )
defparameter   ::=  parameter ["=" expression]
sublist        ::=  parameter ("," parameter)* [","]
parameter      ::=  identifier | "(" sublist ")"
funcname       ::=  identifier

A function definition is an executable statement. Its execution binds the function name in the current local namespace to a function object (a wrapper around the executable code for the function). 函数对象包含一个对当前全局命名空间的引用,作为函数调用时使用的全局命名空间。

The function definition does not execute the function body; 它只有在调用函数的时候才执行。[3]

函数定义可能被一个或多个修饰符表达式封装。修饰符表达式在函数定义时于包含函数定义的定义域中求值。求值的结果必须是一个可调用对象,它以该函数对象为唯一的参数。调用的返回值绑定在函数名而不是函数对象上。多个修饰符是以嵌套的方式作用的。For example, the following code:

@f1(arg)
@f2
def func(): pass

is equivalent to:

def func(): pass
func = f1(arg)(f2(func))

当一个或多个最上层的参数具有parameter = expression的形式时,称该函数具有“默认参数值。” 对于具有默认值的参数,对应的参数在调用时可以省略,在这种情况下使用参数的默认值。如果一个参数具有默认值,所有随后的参数也必须具有默认值 — 这个限制在语法中没有表达出来的。

默认的参数值在执行函数定义时求值。 This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. 一种变通的方法是使用None作为默认值,然后在函数体中明确地测试它,例如:

def whats_on_the_telly(penguin=None):
    if penguin is None:
        penguin = []
    penguin.append("property of the zoo")
    return penguin

Function call semantics are described in more detail in section Calls. A function call always assigns values to all parameters mentioned in the parameter list, either from position arguments, from keyword arguments, or from default values. If the form “*identifier” is present, it is initialized to a tuple receiving any excess positional parameters, defaulting to the empty tuple. If the form “**identifier” is present, it is initialized to a new dictionary receiving any excess keyword arguments, defaulting to a new empty dictionary.

It is also possible to create anonymous functions (functions not bound to a name), for immediate use in expressions. This uses lambda expressions, described in section Lambdas. Note that the lambda expression is merely a shorthand for a simplified function definition; a function defined in a “def” statement can be passed around or assigned to another name just like a function defined by a lambda expression. The “def” form is actually more powerful since it allows the execution of multiple statements.

Programmer’s note: Functions are first-class objects. A “def” form executed inside a function definition defines a local function that can be returned or passed around. 在嵌套的函数中使用的自由变量可以访问包含该def的函数的局部变量。See section Naming and binding for details.

7.7. Class definitions

A class definition defines a class object (see section The standard type hierarchy):

classdef    ::=  "class" classname [inheritance] ":" suite
inheritance ::=  "(" [expression_list] ")"
classname   ::=  identifier

A class definition is an executable statement. 它首先计算inheritance序列,如果存在的话。inheritance序列中的每一项都应该是一个类对象或者允许生成子类的类类型。然后使用一个新创建的局部命名空间和初始的全局命名空间,在新的执行帧中执行类的语句组(参见名称和绑定一节)。(Usually, the suite contains only function definitions.) When the class’s suite finishes execution, its execution frame is discarded but its local namespace is saved. [4]最后使用inheritance序列作为基类创建一个类对象,并保存局部命名空间作为属性字典。The class name is bound to this class object in the original local namespace.

Programmer’s note: Variables defined in the class definition are class variables; they are shared by all instances. To create instance variables, they can be set in a method with self.name = value. Both class and instance variables are accessible through the notation “self.name”, and an instance variable hides a class variable with the same name when accessed in this way. Class variables can be used as defaults for instance variables, but using mutable values there can lead to unexpected results. For new-style classes, descriptors can be used to create instance variables with different implementation details.

Class definitions, like function definitions, may be wrapped by one or more decorator expressions. The evaluation rules for the decorator expressions are the same as for functions. The result must be a class object, which is then bound to the class name.

脚注

[1]异常将扩散到调用栈除非finally子句碰巧引发另外一个异常。这个新的异常导致旧的异常丢失。
[2]目前,控制“从末尾流出”除了下面这些情况:异常或执行returncontinuebreak语句。
[3]作为函数体第一条语句出现的字符串字面值被转换成函数的__doc__属性,即函数的文档字符串
[4]作为类体的第一条语句出现的语句被转换为该命名空间的__doc__属性,即类的文档字符串