# Statements and Control(语句与控制)

  • 语句(statements)与表达式(expressions)不同,它一般不会直接返回值,而是执行一些操作
  • 我们在之前已经遇到了一些语句:赋值语句,函数定义defreturn语句等
  • 注意:纯函数本身作为语句执行没有意义,它会计算表达式的值然后将其丢弃,需要将结果通过赋值语句存储或通过return输出才有意义。

# 复合语句(Compound statements)

  • 复合语句通常由多个简单语句(当然也可以包含复合语句)组成,格式如下:
<header>:
    <statement>
    <statement>
    ...
<separating header>:
    <statement>
    <statement>
    ...
...

其中<header>:作为复合语句的头部确定语句的类型,缩进的语句组合称为句体(suite)。

  • 赋值语句,表达式与返回语句都是简单语句,而def语句就是复合语句。
  • 每类header都有其求值规则规定其在何种条件下执行以及是否执行。
  • 所以,在执行语句序列时,程序会先执行当前第一个语句。如果没有重定向控制,那么就会继续执行序列剩余的语句(如果有的话)。
  • 我们可以将上面的执行规则递归地执行下去(语句内可以嵌套序列),序列语句可以看成递归式的数据结构。

# 函数的局部赋值(Local Assignment)

  • 定义函数时,函数体内可以不止有return语句,还可以对局部变量进行赋值操作
  • 函数内的赋值是将名称与当前环境的第一帧进行绑定,所以对全局帧没有影响(赋值的名称可以是局部变量)
  • 这对于建立模块化程序非常有用,这样别的程序可以直接调用整个模块,而不需要重新再全局环境中重新编写
  • 在函数内局部赋值,在与其他控制语句结合时会有较好的效果;
  • 另外,函数体内的中间变量名称也能增强程序的可解释性。

# 条件语句(Conditional Statements)

  • if语句,由一系列头部和句体组成:
if <expression>:
    <suite>
elif <expression>:
    <suite>
else:
    <suite>

其中elif,else均为可选子句。

  • 程序执行条件语句时,会先按顺序求解子句头部的表达式。如果表达式值为真,则执行对应的句体,再跳过其他所有后续子句。
  • 如果到了else子句(当且仅当前面的子句表达式均为假),那么就执行else句体。
  • 假值包括0NoneFalse,而真值包括其他所有数字。
  • 注:你可能认为条件语句可以通过调用一个函数实现(类似if_(c,t,f),当c为真时返回t,否则返回f)。但二者之间的一大区别是,函数会将所有参数表达式进行计算,而条件语句只会计算头部语句为真的对应表达式的计算。

# 布尔语境(Boolean contexts)与布尔值

  • 上述条件块头部语句中的表达式称为布尔语境,控制句体的执行与否;同时这里的表达式不会被赋值或返回
  • 在python中,有两个布尔值:TrueFalse,对应逻辑表达式中的真与假;
  • 使用比较运算符会返回布尔值:
>>> 4 < 2
False
>>> 5 >= 5
True
>>> 3 != -3
True
>>> 0 == -0  #注意与赋值操作'='区分
True
  • 也可以使用布尔运算符返回布尔值:
>>> True and False
False
>>> True or False
True
>>> not True
False
>>> True or 114514 # 这个例子比较特殊
114514
>>> 33 or 16
33
>>> print(10) or "" # 这个例子比较cheeky
10
""
  • 注意在计算这些逻辑表达式时,并不一定会计算所有的表达式(被称为 “短路”short-circuiting ):
    • 计算<left> and <right>时,如果<left>值为真,则返回<right>的值,否则返回<left>的值;
    • 计算<left> or <right>时,如果<left>值为假,则返回<left>的值,否则返回<right>的值。
  • 返回布尔值的函数通常名称以is开头,如isprime

# 迭代(Iteration)

  • 有时,程序需要重复执行相同的语句,提高计算的效率
  • 而控制语句就可以实现多次执行相同语句,称为迭代控制(Iterative control)。
  • 常常会使用到while语句:
while <expression>:
    <suite>

执行while语句时:

  • 判断<expression>里的值是否为真。若为假,结束语句执行。
  • 若为真,那么就执行后面的句体。再返回上一步。
    注意:句体里的语句执行应该能影响表达式值的真假,否则会导致无限循环(Infinity loop)。
  • 当然也可以在句体中设置if-break语句,主动结束语句。

# 测试

  • 在设计完函数后,需要及时测试函数的功能。
  • 通常使用另一个函数进行测试,在函数中将参数赋值,将输出结果与期望的结果进行比较。

# 断点测试(Assertions)

  • python中,可以使用assert语句对函数的输出进行测试,格式一般如下:
>>> def fib_test():
        assert fib(2) == 1, '第二个斐波那契数应该是 1'
        assert fib(3) == 1, '第三个斐波那契数应该是 1'
        assert fib(50) == 7778742049, '在第五十个斐波那契数发生 Error'
  • 语句会对布尔语境下的表达式进行逻辑判断,如果结果为真则不会执行,如果为假则会执行语句,输出字符串,同时程序也会提前终止。
  • 测试时一般会对一些极端情况进行测试,以验证函数的功能完整性。

# 文档测试(doctests)

Chapter 2