`
小聂飞
  • 浏览: 17624 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
社区版块
存档分类
最新评论

Python 3.3 教程 - 4 Python中的流程控制

 
阅读更多

 

原文请参见: http://docs.python.org/3/tutorial/controlflow.html

 

 

除了刚才介绍的while语句外,Python支持通常其它语言支持的流程控制语句,只是略有变动。

 

4.1 if语句

 

也许最有名的语句就是if语句了,比如:

 

 

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...      x = 0
...      print('Negative changed to zero')
... elif x == 0:
...      print('Zero')
... elif x == 1:
...      print('Single')
... else:
...      print('More')
...
More

 

elif部分可有多个或没有,同时,else部分是可选的。关键字'elif'比'else if'要短很多,它可以避免过多的缩进。Python里面没有switch或者case这种语句,不过你可以使用if...elif...elif...来实现。

 

4.2 for语句

 

Python中的for语句和C或Pascal中的for有点不一样。Python中的for语句不像其它编程语言中for语句那样去遍历等差数列的数字(Pascal),或者用户定义一个结束条件和遍历的步数(C),Python的for语句用来遍历任意序列中的项(列表或者是字符串),以它们在序列中出现的次序进行遍历,比如:

 

 

>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12

 

如果你在遍历序列的循环中去修改这个序列的话,建议你可以先做一个序列的拷贝。遍历序列并不会隐式的产生一个拷贝。分片符使得这些操作异常的简单:

 

 

>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

 

4.3 range()函数

 

如果你需要遍历一连串数字的时候,你可以使用内建函数range(),它可以产生等差数列:

 

 

>>> for i in range(5):
...     print(i)
...
0
1
2
3
4

 

生成的数字并不会包含给定的结尾数字,range(10)会产生10个数值,同时有10个合法的索引值。当然,你也可以让这个范围从另一个数字开始,或者指定一个其它的增量(或负增量,有些地方也叫步长):

 

 

range(5, 10)
   5 through 9

range(0, 10, 3)
   0, 3, 6, 9

range(-10, -100, -30)
  -10, -40, -70

 

为了遍历一个序列的索引,你可以结合使用range()和len():

 

 

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

 

在绝大多数场景中,建议使用更方便的enumerate(),详细信息请参考:Looping Techniques

 

当你打印一个range时,你会发现结果有点奇怪:

 

 

>>> print(range(10))
range(0, 10)

 

我们感觉range()函数返回的对象的行为有点像列表,但实际上它只有在你遍历的时候会返回符合条件的序列项,但它并不会真正的产生一个列表,因此个函数是节省空间的。

 

我们称这种对象是可遍历的,在函数或者结构中可以使用这种对象获取符合条件的序列项直到条件不满足为止。我们已经看到for语句中是一种遍历,另外,list()函数是另一个例子,它会根据传入的可遍历对象来创建列表:

 

 

>>> list(range(5))
[0, 1, 2, 3, 4]

 

稍后,我们将会看到更多的函数可以返回可遍历对象或者把可遍历对象作为参数。

 

 

 

4.4 break 和 continue语句,循环中的else块

 

break语句和C中的用法一样,用来跳出for或者是while循环。

 

在Python中,循环语句也可能有else语句块。循环中的else语句块是当循环正常结束之后才执行(访问的列表遍历到最后了,自定义条件为false了等等),如果是非正常结束的话就不会执行,比如循环中执行了break语句。请参看一下例子,该例子程序用来寻找素数:

 

 

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

 

请注意,以上代码是正确的代码,其中else是属于for循环的,并不是属于if语句的。

 

else块使用在循环中时,有点像else使用在try语句块中:try语句的else块是在没有异常产生的时候才执行,循环的else语句块是在没有break产生的时候才执行。对于try语句的更多信息,请参考:Handling Exceptions

 

 Continue语句当然也和C语言中的一样了,用来在循环中继续执行下一趟遍历:

 

 

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

 

 

4.5 pass语句

 

pass语句就是什么都不做。它可以在你不需要程序做什么事情,但是语法需要你做一些事情的时候来使用。比如:

 

 

>>> while True:
...     pass  # Busy-wait for keyboard interrupt (Ctrl+C)
...

 

 

该语句经常被用来创建最下的类:

 

 

>>> class MyEmptyClass:
...     pass
...

 

 

另一个pass使用的地方是当你在设计新代码的时候它可以充当占位符的作用,允许你以一个非常抽象的层次上思考问题。比如:

 

 

>>> def initlog(*args):
...     pass   # Remember to implement this!
...

 

 

4.6 函数定义

 

 我们可以创建一个函数来实现Fabonacci序列以任意的数值为边界:

 

 

>>> def fib(n):    # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

 

 

关键字def用来定义一个函数。在它后面必须紧跟函数名和括号括起的参数列表。同时,函数体从下一行开始,并且必须要缩进。

 

函数体的第一个语句可以是一个可选的字符串常量;该字符串常量是该函数的文档字符串,或者文档说明。有专门的工具可以自动的根据该文档字符串生成在线的文档或者是可打印的文档,再或者可以让用户在代码中互动的去浏览该说明。当你写代码的时候,包含一些文档说明是一个很好的习惯,你应该注意培养。

 

函数执行的时候会引入一个新的符号表来供函数的本地变量使用。更精确的讲,函数中所有的赋值变量被保存在本地符号表中;所以在引用变量的时候会先在本地符号表中进行查找,然后会在外围函数的本地符号表中查找,再然后才会在全局表中查找,最后则会在内建的变量表中查找。因此,全局的变量不能在函数中被直接赋值(除非你在一个global语句中命名),但是它们可以是被引用的。

 

在函数调用时的实际参数被保存到被调用函数的本地符号表中,因此,函数调用中的参数传递是一种传值的方式传递的。当一个函数调用另一个函数时,一个新的本地符号表将会创建。

 

函数定义的时候会在当前的符号表中引入函数的名字。函数的名字作为一个值的类型可以被解释器作为用户自定义的函数所识别。函数名字的值可以被赋值成其它的名字,赋值之后的名字也可以作为函数来使用。这作为一种通用的函数重命名机制:

 

 

>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89

 

如果你学的是其它的语言,你可能会认为fib并不是一个函数,而是一个过程,因为它没有返回任何值。实际上,即便一个函数没有reture语句,它依然会返回一个值。这个值叫做None,它是一个内建的名字。你直接输入None通常解释器并不会显示它。当然,你可以通过print()语句来看到它的真正数值:

 

 

>>> fib(0)
>>> print(fib(0))
None

 

 

当然,如果你不想打印它,你也可以直接返回一个Fibonacci序列的列表:

 

 

>>> def fib2(n): # return Fibonacci series up to n
...     """Return a list containing the Fibonacci series up to n."""
...     result = []
...     a, b = 0, 1
...     while a < n:
...         result.append(a)    # see below
...         a, b = b, a+b
...     return result
...
>>> f100 = fib2(100)    # call it
>>> f100                # write the result
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

 

以上的例子,证明了Python的一些新特性:

 

  • return语句会从函数中返回一个值。仅仅只有return的话会返回None.即便函数结尾没有return语句依然会返回None.
  • 语句result.append(a)调用了列表对象result的一个方法。(NF:就是对象调用方法的东西了,如果学Java的话很容易明白这个形式是在对象上执行方法。)

 

 

4.7 函数定义中的更多内容

 

如果你想在定义函数的时候定义可变的参数列表,那么有三种形式,同时,这三种形式是可以组合的。

 

 

4.7.1 默认参数值

 

最有用的形式就是为一个或者多个参数设置默认值。通过这种方式,创建出来的函数可以用更少的参数即可进行调用。比如:

 

 

def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
    while True:
        ok = input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise IOError('refusenik user')
        print(complaint)

 

这个函数可以通过以下几种方式进行调用:

 

  • 仅给出必须的参数: ask_ok('Do you really want to quit?')
  • 给出可选的参数:ask_ok('OK to overwrite the file?',2)
  • 给出所有的参数:ask('OK to overwrite the file?',2,'Come on, only yes or no!')

 

这个例子引出了关键字 in。该关键字用来测试一个序列是否包含某个值。

 

参数的默认值在定义函数的时刻会被计算,如:

 

 

i = 5

def f(arg=i):
    print(arg)

i = 6
f()

 

将会打印 5.

 

注意:默认值仅仅会被计算一次。但这个规则对于可变的对象,如列表,字典或者是大多数类的实例来说又是不同的。比如,下面的函数例子将会把所有后续调用的参数都收集起来:

 

 

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

 

将会打印如下:

 

 

[1]
[1, 2]
[1, 2, 3]

 

如果你不想被在后续调用之间共享,你可以修改函数如下:

 

 

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

 

 

4.7.2 关键字参数

 

函数也可以通过使用关键字参数来进行调用,关键字参数的形式是:kwarg=value。比如,对于一下函数:

 

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):

    print("-- This parrot wouldn't",action,end=' ')

    print("if you put",voltage,"volts through it.")

    print("-- Lovely plumage, the", type)

    print("-- It's", state,"!")

 

接受一个必须的参数(voltage)和三个可选的参数(state,action,type).这个函数可以通过以下几种方式进行调用:

 

parrot(1000)                                            #1 positional argument

parrot(voltage=1000)                               #1 keyword arguments

parrot(voltage=1000, action='VOOOOM')  #2 keyword arguments

parrot(action='VOOOM',voltage=1000)     #2 keyword arguments

parrot('a million', 'bereft of life', 'jump')       #3 positional arguments

parrot('a thousand', state='test')                #1 positional, 1 keyword

 

但是以下调用是不合法的:

 

parrot()                              #required argument missing

parrot(voltage=5.0, 'dead')  #non-keyword arg after a keyword arg

parrot(110, voltage=220)    #duplicate value for the same argument

parrot(actor='john cleese')  #unknown keyword argument           

 

在一个函数调用中,关键字参数必须要放在有位置型参数后面。所有传入的关键字参数必须匹配函数所接受的参数,比如actor不是合法的参数对于parrot函数来说。但是,关键字参数的次序并不是重要的。对于非可选的参数这也是适合的,比如parrot(voltage=1000)是合法的。同时请注意,相同的参数传入两次也是非法的,比如:

 

 

>>> def function(a):
...     pass
...
>>> function(0, a=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: function() got multiple values for keyword argument 'a'

  如果一个参数的传入形式是**name的话,它表示接收一个字典类型的参数。这可能与*name这种格式的参数有点搅合,*name这种参数将会在下一节进行介绍,*name的格式表示一个元祖类型的参数,同时我们需要知道*name必须要出现在**name之前。比如,如果我们定义如下函数:

 

 

def cheeseshop(kind, *arguments, **keywords):
    print("-- Do you have any", kind, "?")
    print("-- I'm sorry, we're all out of", kind)
    for arg in arguments:
        print(arg)
    print("-" * 40)
    keys = sorted(keywords.keys())
    for kw in keys:
        print(kw, ":", keywords[kw])

 

调用将会如一下方式:

 

 

cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")

 

执行的结果如下:

 

 

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch

 

 

4.7.3 任意的参数列表

 

最后,最不常用的是定义一个可以通过任意参数调用的函数。这些参数被包裹到一个元祖里面。在可变个数参数之前,可以出现零个或多个常规的参数:

 

def write_multiple_items(file,separator,*args):

    file.write(separator.join(args))

 

通常,这些可变的参数是出现在参数列表的最后面,因为它们将所有的参数输入整个传给函数。有且只有关键字参数可以出现在可变参数之后。

 

 

>>> def concat(*args, sep="/"):
...    return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'

 

 

4.7.4 参数列表的解包

 

一个反向的情况是参数已经放置到一个列表或者元祖,但是当在调用函数的时候需要解包操作,因为函数是需要接收不同位置的参数的。如,内建函数range()需要一个起始和终结参数。如果它们不能分别给定的话,在调用函数的时候可以通过*-操作来对列表或者元祖的参数进行解包:

 

 

>>> list(range(3, 6))            # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))            # call with arguments unpacked from a list
[3, 4, 5]

 

同样的,字典类型的关键字参数可以通过**-操作来进行解包操作:

 

 

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print("-- This parrot wouldn't", action, end=' ')
...     print("if you put", voltage, "volts through it.", end=' ')
...     print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

 

 

 

4.7.5 Lambda形式

 

应广大人民群众的要求,一些比如在Lisp中常见的特性被加入进了Python中. 有了lambda关键字,一些小的匿名函数可以被创建出来.这里有一个函数可以返回两个参数之和: lambda a, b: a+b. Lambda形式可以被用在需要使用函数对象的地方. 这中形式在语法上只是一个单独的表达式. 从语义上讲,这种形式只是给创建普通函数一个语法上的糖果. 和嵌套函数定义一样,lambda格式可以从包含它的范围中引用变量:

 

 

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

 

 

 

4.7.6 文档字符串

这里有一些关于文档字符串的内容和格式的一些约定。

 

第一行应该是对象目的的简短总结性描述。简单来讲,它不应该是对对象的名字或类型的表述,因为这些可以通过其它的方式获得。该行应该以大写字符开头,并且以句号结尾。

 

如果文档的字符串有多行,通常第二行将会是一个空行,目的是可以将总结性描述和剩下的详细描述分离开来。接下来的可以是一个或者多个段落,用来描述该对象的调用约定,或者是它的副作用等等。

 

Python解析器不会剥离多行字符中的缩进,如果需要的话,处理文档的工具必须自己来处理剥离缩进。处理方式可以采用如下的约定。第一行之后的第一个非空行决定着整个文档的缩进量。(我们不能使用第一行,因为第一行通常紧靠着引号,所以它的缩进量几乎是不明显的)。空格会被当作缩进而被剥离掉。一般情况下,缩进减少的 行是不应该存在的(比如本身缩进四个空格,这里你却缩进了两个!),但是如果它们发生了的话,所有它们之前的空格都会被剥离掉。空格的等价缩进应该需要测试一下如果你扩展了你的TAB键的话,比如原来可能是一个缩进等价于四个空格,你修改了之后可能一个TAB对应八个空格了。

 

以下是一个例子:

 

 

>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.

    No, really, it doesn't do anything.

 

 

4.7.7 函数注解

 

基本不用,就不说了,感兴趣的同学可以看一下官方说明。

 

 

4.8 编码风格

 

编码风格的话有以下几点:

 

1. 采用四个空格作为缩进,而不是TAB。

 

2. 当一行的字符达到79个的时候,注意换行。

 

3. 采用空行来分隔函数、类和函数中比较大的代码块。

 

4. 如果可能的话,还是添加一些注释在代码行上。

 

5. 采用docstrings。

 

 

 

 

分享到:
评论

相关推荐

    python 3.3

    python3.3安装包,方便使用 直接安装

    Pydev for python3.3

    Python 环境搭建 一Python的开发环境IDLE 和 Pydev 这里使用Pydev 和 eclipse...二Python 简介 python程序是由解释器来执行的。通常只要在dos命令窗中输入python命令即可启动解释器; 例如: Dos窗口下输入HelloWorld

    赵璐python教程答案-《Python语言程序设计教程》赵璐著【摘要书评在线阅读】-苏宁 .pdf

    2.2 标识符及命名规则 2.3 变量与赋值语句 2.4 数据的输⼊与输出 2.5 数值 2.6 字符串 2.7 混合运算和类型转换 本章⼩结 课后习题 第3章 程序流程控制 3.1 条件表达式 3.2 选择结构 3.3 循环结构 3.4 random库的基本...

    python3.3入门指南

    资源名称:python 3.3 入门指南内容简介:Python是一门简单易学且功能强大的编程语言。它拥有高效的高级数据结构,并且能够用简单而又高效的方式进行面向对象编程。Python 优雅的语法和动态类型,再结合它的解释性,...

    Python-3.3-官方入门指南(带目录)

    Python 是一门简单易学且功能强大的编程语言。它拥有高效的高级数据结构,并且能够用简单而又...Python 优雅的语法和动态类型,再结合它的解释性,使其在大多数平台的许多领域成为编写脚本或开发应用程序的理想语言。

    python3.3使用手册

    从网上找了好久才找到中文的python3.3的入门学习资料,免费分享给大家!

    win python3.3 2048 exe

    win python3.3 2048 exe 用cx_feeze打包的python3.3 tkinter程序

    python菜鸟基础教程-终于懂得python入门菜鸟教程.pdf

    ⼆、python⾃带的集成开发环境,可通过开始——所有程序——python3.3——IDLE(Python GUI)启动。三、其他集成开发环境,如 PythonWin等,有编辑和调试能⼒,还实现了MFC类库存的包装。 本例中,使⽤python⾃带的...

    Python 3.3绿色精简单文件版

    Python 3.3的绿色精简单文件版,一个exe文件包括所有的运行环境,windows环境下都能运行。适合用于学习或者为自己写的程序扩展python功能。

    python 3.3下结合tkinter做的猜数字程序

    python 3.3下结合tkinter做的猜数字程序,供大家一起共同分享学习。

    python-3.3.1.zip

    常常被拿来跟Java、Perl等语言相比较的一个物件导向的Script程序语言,与Java一样使用具有跨平台移植特性Bytecode,语法清晰,易学易用,可与其他语言混合使用,有不少专业的人士预测Python是继Java之后的明日之星。...

    python案例教程钱毅湘-Python案例教程.pdf

    python案例教程钱毅湘_Python案例教程 章 Python语⾔基础 1.1 知识要点 1.1.1 程序设计概述 1.1.2 Python语⾔概述 1.1.3 Python程序的格式框架 1.1.4 常量和变量 1.1.5 Python数据类型 1.1.6 基本运算 1.1.7 Python...

    Python灰帽子-黑客与逆向工程师的Python编程之道[简体中文版]

    作者借助于如今黑客社区中备受青睐的编程语言Python引领读者构建出精悍的脚本程序来一一应对上述这些问题。出现在本书中的相当一部分Python代码实例借鉴或直接来源于一些优秀的开源安全项目,诸如Pedram Amini的...

    Python示例-从基础到高手PDF

    第 18 章 如何将 Mac OS X10.9 下的 Python2.7 升级到最新的 Python3.3 第 19 章 使用 python 构建基于 hadoop 的 mapreduce 日志分析平台 第 20 章 报警监控平台扩展功能 url 回调的设计及应用 [python 语言] 第...

    Python学习笔记(干货) 中文PDF完整版.pdf

    4、Python中的常见运算符 4.1 算术运算符 4.2 关系运算符 4.3 逻辑运算符 4.4 位运算符 4.5 成员运算符 4.6 身份运算符 5、Python中的分支结构 5.1 单向分支-if语句 5.2 双向分支-if 5.3 多分支-if 5.4 ...

    Mac OS X10.9安装的Python2.7升级Python3.3步骤详解

    第1步:官网下载Python3.3 这里面有windows和mac os x下的安装程序,下载那个64位的安装程序 第2步:安装下载的img文件,安装完后的目录如下:复制代码 代码如下:/Library/Frameworks/Python.framework/Versions/3.3...

    深入Python_zh-cn[中文版]

    第一个 Python 程序........................................................................................18 2.1. 概览...................................................................................

    Python基础教程之控制结构详解.pdf

    在《Python基础教程》的系 列博⽂中,我们已经介绍了 Python 中的内置原⽣数据类型,并且也了解了程序如何利⽤输⼊、输出语句与⽤户进⾏交互。本节的主要⽬标是 介绍 Python 的控制语句,为接下来的学习奠定基础,本...

    Python基础编程全教程+实践案例

    非常适合Python入门的全教程,Python 基础教程 2、 Python概述 2.1 认识Python 2.2 Python的安装 2.3 集成开发环境Pycharm 3、 第一个Python程序 3.1 Python程序执行原理 3.2 Python程序文件执行 3.3 Python...

    python-u2flib-server, 基于 python的U2F服务器库.zip

    python-u2flib-server, 基于 python的U2F服务器库 u2flib-server提供与U2F协议的服务器端方面的功能,如 FIDO规范中定义的那样。 它支持 python 2.7,python 3.3 和 PyPy 2.7 。要了解有关U2F以及如何使用U2F库的更...

Global site tag (gtag.js) - Google Analytics