重温Python的知识结构

  1. 程序由模块组成。
  2. 模块包含语句。
  3. 语句包含表达式。
  4. 表达式创建并处理对象。

从基础上看,Python编写的程序实际上时由语句和表达式构成的。表达式用于处理对象,并被嵌入到语句中。语句使用并引导表达式处理我们前几章所学的对象。

语句可以创建对象。

Python的语句

下表总结了Python的语句集。其中,有些语句已经在前面的章节中使用到。

语句 功能 示例
赋值 创建引用值 a, b = 'good', 'bad'
调用与其他表达式 运行函数 log.write("spam, ham")
print调用 打印对象 print('The Killer', joke)
if/elif/else 选择动作 if "python" in text:
print(text)
for 序列迭代 for x in mylist:
print(text)
while 通用循环 while X > Y:
print('hello')
pass 空占位符 while True:
pass
break 循环推出 while True:
if exittest(): break
continue 循环继续 while True:
if skiptest(): continue
def 函数与方法 def f(a, b, c=1, *d):
print(a+b+c+d[0])
return 函数结果 def f(a, b, c=1, *d):
return a+b+c+d[0]
yield 生成器函数 def gen(n):
for i in n: yield i*2
global 命名空间 x = 'old'
def function():
global x, y; x = 'new'
nonlocal 命名空间 def outer():
x = 'old'
def function():
global x, y; x = 'new'
import 获取模块 import sys
from 获取属性 from sys import stdin
class 构建对象 class Subclass(Superclass):
staticData = []
def method(self): pass
try/except/finally 捕捉异常 try:
action()
except:
print("action error")
raise 触发异常 raise EndSearch(location)
assert 调试检查 assert X > Y, 'X too small'
with/as 上下文管理器(3.X,2.6+) with open('data') as myfile:
process(myfile)
del 删除引用 del data[k]
del data[i:j]
del obj.attr
del variable

说明:

  • 赋值语句有多种形式:基本的、序列的、扩展的。
  • print在Python 3.X是一个内置函数调用,在Python 2.X是一个语句。
  • yield在Python 3.X也是一个表达式,而不是语句。

版本2.X的特性:

  • nonlocal不可用。
  • exec是一个语句,有特定的语法。
  • try/excepttry/finally合并(2.5)。
  • with/as需要导入模块__future__中的with_statement

两种不同的if

这里着重说明Python的语法与C/C++的语法的不同。以if为例,在C/C++是这么写的:

if (x > y){
    x = 1;
    y = 2;
}

Python是这么写的:

if x > y:
    x = 1
    y = 2

看上去,Python更简洁。

Python增加的元素

Python增加了冒号:,所有的Python复合语句(即内嵌了其他语句的语句)都是如此,即首行以冒号结尾,下一行嵌套的代码缩进:

Header line:
    Nested statement block

Python删除的元素

括号是可选的

首先是语句第一行的括号:

if (x > y){

在Python中,可以不用括号。虽然用括号不会报错,但不用括号更接近Python风格。

行终止就是语句终止

在C/C++中,语句以分号;终止。一般情况下,Python的语句以一行的结束为结束而不需要分号。也就是说,x = 1 会被视为一个语句。但是,如果用一些特殊手段,Python的语句会变为多行。

缩进的结束就是代码块的结束

在C/C++中,代码块以左大括号{开始,以右大括号}结束。在Python中,代码块以开始缩进为开始,以结束缩进为结束。这里,代码块就是第2-3行。缩进就是:左侧留空白。

if x > y:
    x = 1
    y = 2
a = 1

为什么采用缩进语法

根据逻辑结构将代码对齐是使程序具有可读性的重要步骤。实际上,编写任何语言的代码都需要通过缩进来提高可读性,成熟的IDE也支持自动缩进。

经验法则:不应该在同一段Python代码中混合使用制表符\t和空格,否则会引发错误。

几种特殊情况

在Python语法模型中:

  • 一行的结束就终止了该行语句(没有分号)。

  • 嵌套语句通过它们的缩进,来划分代码块(没有大括号)。

语法规则的特殊情况

一行挤进多条语句,此时这些语句由分号隔离的情况:

>>> a = 1; b = 2; print(a + b)
3

只有当摆到一起的语句本身不是复合语句时才这么做,如果有ifwhile等语句最好单独开一行。

一条语句的范围横跨多行的情形。实现这一操作只需要用一对括号把语句括起来。任何括在这些符号里的代码都可以跨越好几行,直到Python遇到闭合括号的那一行。

mylist = [1111,
	      2222,
	      3333]

这里程序被括在一对方括号里,因此Python接着运行下一行,直到遇见闭合的方括号为止。大括号中的字典集合、中括号的序列、小括号的元组都可以这么用。

括号可以包含一切,包括表达式和复合语句:

X = (A + B +
     C + D)
if (A == 1 and
    B == 2 and
    C == 3):
    print('spam' * 3)

还有一种方法能够跨越数行——用反斜线。

X = A + B + \
    C + D

这种方法容易引发错误(反斜线不能有空格),因此不推荐。

代码块规则的特殊情况

复合语句的主体如果只有一行,可以出现在Python的首行冒号之后:

if x > y: print(x)

当然,这种情况只适用于复合语句本身只包含一个简单语句的情况。也可以用多个语句用分号挤进一行(但不推荐)。

简短示例:交互式循环

一个简单的交互式循环

假设有人要求写一个程序,要求在控制窗口与用户交互。准确的说,要求用户键盘输入数据的循环并打印每次读取的结果。我们需要写一个标准的“读取/计算/打印”的循环程序。

这种程序类似于:

while True:
    reply = input('Enter text:')
    if reply == 'stop': break
    print(reply.upper())

以下是这段代码的解释:

  • 这段代码利用率Python的while循环,它后面跟着一个表达式,可能是真或者是假,冒号后面是当表达式为真时,执行的复合语句。当复合语句执行完毕,在回到while循环重新判断表达式的真假。
  • input用于控制台输入,它的参数是一个字符串,当执行到这一语句,input输出这个字符串,读取用户输入的内容并返回用户输入的内容。
  • 单行的if在这里出现。
  • break语句会跳出当前的循环。

这段代码的功能是:从用户读取一行输入,并转换成大写字母打印,直到用户输入stop为止。注意到,while首行下面的三行代码都有同样程度的缩进,这意味着它们都是与while相关联、重复的代码块。

对用户输入做数学运算

以刚才的交互式循环为基础,我们要做一些数学运算。比如,每一次循环,输入一个数,返回这个数的平方:

while True:
    reply = input('Enter text:')
    if reply == 'stop': break
    print(int(reply) ** 2)
print('Bye')

用户输入的数是以字符串类型表示的,但是只有数值类型才能进行平方运算。因此我们要通过int函数把字符串转换为整数。

这里的程序在末尾加了输出'Bye'的信息。由于它没有缩进,故不是循环体的一部分。也就是说,跳出循环后这个语句才会执行。

通过测试输入数据来处理错误

对应刚才的程序而言,如果我们输入了处数字和stop以外的内容,会出现错误。

Enter text:123
15129
Enter text:?
Traceback (most recent call last):
  File "<.py文件的绝对路径>", line 4, in <module>
    print(int(reply) ** 2)
ValueError: invalid literal for int() with base 10: '?'

这是因为我们刚才忽略了“乱输入”的情况。我们可以用字符串对象的isdigit方法检查字符串是否为一个数字:

while True:
    reply = input('Enter text:')
    if reply == 'stop':
        break
    elif not reply.isdigit():
        print('Bad!' * 8)
    else:
        print(int(reply) ** 2)
print('Bye')

这里,ifelifelse是同一个语句的组成部分,Python执行语句时会从上到下检测冒号前面的表达式是否为真,如果为真则执行代码块,否则跳到代码块下一行。接着,整个if区块都在while循环的一部分。

运行时,如果输入的既不是数字,也不是stop,那么程序会在错误发生前捕捉它,并打印错误消息,否则其行为与之前的程序不变。

用try处理错误

try也可以捕捉错误并做出反应。

while True:
    reply = input('Enter text:')
    if reply == 'stop': break
    try:
        num = int(reply)
    except:
        print('Bad!' * 8)
    else:
        print(num ** 2)
print('Bye!')

try是一种复合语句,其组成是:try关键字后面跟着一个代码块,再跟着一个提供异常处理代码的except部分、以及没有引发异常时执行的else部分。Python首先执行try后面的代码块,如果有异常,则执行except的代码块,否则执行else的代码块。

对浮点数的支持

如果我们不只是要计算整数的平方,我们可以用float()方法把字符串转化为浮点数。但是,此时我们不能用isdigit()函数了,也就是第一种方法不行。

嵌套三层深的代码

我们可以进一步改进。比如,我们根据输入的大小,决定是否打印结果。

while True:
    reply = input('Enter text:')
    if reply == 'stop':
        break
    elif not reply.isdigit():
        print('Bad!' * 8)
    else:
        num = int(reply)
        if num < 20:
            print('low')
        else:
            print(int(reply) ** 2)
print('Bye')

这个版本把一个if语句嵌入另一条if语句的else部分。当出现这样嵌套的情形时,我们只需要再向右缩进即可。

posted on 2024-11-15 17:50  晓小稻  阅读(56)  评论(0编辑  收藏  举报