Skip to content

Latest commit

 

History

History
273 lines (241 loc) · 9.88 KB

File metadata and controls

273 lines (241 loc) · 9.88 KB

More Control Flow Tools

if循环语句

if语句哪个语言都有,python的else if写成了elif:

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

for语句

这个跟很多语言都不相同,倒是跟C#的foreach的用法有点类似:

>>> #Measure some strings:
... words=['cat','window','defenetrate']
>>> for w in words:
...     print w,len(w)
...
cat 3
window 6
defenetrate 11
>>> for w in words[:]:
...     if len(w)>6:
...         words.insert(0,w)
...
>>> words
['defenetrate', 'cat', 'window', 'defenetrate']

如果要改变正在迭代的列表 (例如, 复制选中的项), 应该对复本进行迭代. 通常用切片能方便的作到,如上。

range()函式

range()是创建数值序列的,这个是创建等值序列:range(n); range(n,m)是创建从n开始到m(不包含m)的序列; range(n,m,r)是创建从n开始,每次增长r,到m(不包含m)数的序列。

>>> print range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print range(5,10)
[5, 6, 7, 8, 9]
>>> print range(0,10,3)
[0, 3, 6, 9]
>>> print 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

break和continue循环语句,以及else在循环中的子句

break是跳出最小的for或者while循环; continue继续循环下一次迭代; else在for或者while循环完这个列表而终止或者条件变假被执行。

>>> for n in range(2,10):
...     for x in range(2,n):
...         if n % x==0:
...             print n,'equals',x,'*',n//x
...             break
...     else:
...         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

pass语句

pass 语句什么都不做. 当语法上需要一个语句, 但程序不要动作时, 就可以使用它. 例如:

>>> while True:
...     pass  # 忙等待键盘中断 (Ctrl+C)
...

定义函数

菲波那契(Fibonacci) 数列:

>>> def fib(n):
...     """打印到n的Fibonacci序列。"""  
...     a,b=0,1
...     while a<n:
...         print a,
...         a,b=b,a+b
...
>>> #现在我们调用这个函数  
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

上面是打印,我们一般要的是一个序列,返回我们需要的:

>>> def fib2(n): # 放回直到 n 的 Fibonacci 序列
...     """返回一个列表, 包含直到 n 的 Fibonacci 序列."""
...     result = []
...     a, b = 0, 1
...     while a < n:
...         result.append(a)    # 见下文
...         a, b = b, a+b
...     return result
...
>>> f100 = fib2(100)    # 调用
>>> f100                # 输出结果
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

深入函数定义

默认参数

可以给定一个或者更多参数的默认值,这样调用的就可以不用给足参数值。

def ask_ok(prompt,retries=4,complaint='Yes or no,please !'):
	while True:
		ok=raw_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('OK to overwrite the file?', 2, 'Come on, only yes or no!') 这里面也有个in 关键字,用以验证序列中是否包含这个值。

关键字参数

关键字参数说白了就是这样:key=value来调用函数,有几种需要注意:
当一个必须参数(就是没有给定值得参数)用了关键字参数传参,那么,它后面的参数也必须是关键字参数,例如:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
	print "-- This parrot wouldn't", action,
	print "if you put", voltage, "volts through it."
	print "-- Lovely plumage, the", type
	print "-- It's", state, "!"

如下调用可行:

parrot(1000)                                          # 1 positional argument
parrot(voltage=1000)                                  # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM')             # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump')         # 3 positional arguments
parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

如下调用不可行:

parrot()                     # required argument missing
parrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argument
parrot(110, voltage=220)     # duplicate value for the same argument
parrot(actor='John Cleese')  # unknown keyword argument

定义参数的时候还可以按照 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

上面有个函数是keys(),是对字典进行排序,这样打印出来的是可控的顺序,不然就比较随意。

任意参数表

可以随意定义参数,这些参数会被包装进一个元组,在变长参数之前,可以使用0或者多个正常的参数:

def write_multiple_items(file, separator, *args):
	file.write(separator.join(args))

解包参数列表

参数本来已经是一个列表或者元组时,我们需要将其分解作为参数值,用于函数的参数,用的操作符是“*”,
例如:

>>> list(range(3,6))
[3, 4, 5]
>>> args=[3,6]
>>> list(range(*args))
[3, 4, 5]

当然也可以使用‘**’操作符:

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     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 !

Lambda形式

使用关键字 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
>>> f(-12)
30
>>> f(1)
43
>>> f(3)
45

要补一下内嵌函数的用法,这个地方没有弄明白怎么实现的。

文档字符串

可以在定义函数的名称的下边写上注释,但是在注释一行写不完的情况下,空一行再写,以能从视觉上分隔概述和其它部分。
官方还有一个解释,在不是空白行的第二行注释中,前面的留白的作用:
在文档字符串第一行 后 的第一个非空行决定整个文档字符串缩进的数量.
(我们不使用第一行的原因是它通常与字符串的外引号相连而使得它的缩进不明显.)
留白 “相当于” 是文档字串的起始缩进将会被清除. 每行不应该当有不足的缩进, 如果有前导空白,
将会全部清除. 由制表符扩展成的空白应该测试是否可用(一般被兑换成 8 个空格)。

 >>> 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-空格 缩进, 且没有制表符.
    4 空格是在小缩进 (允许更多嵌套) 和大缩进 (更易读) 之间的好的妥协. 制表符会带来混乱, 最好不要使用.
  • 设定自动换,使它们不超过 79 个字符.
    这会帮助小屏幕的用户, 而且使得可以在大屏幕上同时显示几个代码文件成为可能.
  • 使用空行分隔函式和类, 以及函式中的大的代码块.
  • 尽可能令注释独占一行.
  • 使用文档字串.
  • 在操作符两边, 逗号后面使用空格, 但是括号内部与括号之间直接相连的部分不要空格: a = f(1, 2) + g(3, 4).
  • 保持类名和函式名的一致性; 约定是, 类名使用 CamelCase 格式, 方法名和函式名使用 lower_case_with_underscres 形式.
    永远使用 self 作为方法的第一个参数名 (参阅 类的初印象 获得更多有关类和方法的信息).
  • 若代码打算用在国际化的环境中, 那么不要使用奇特的编码. Python 默认的 UTF-8, 或者甚至是简单的 ASCII 在任何情况下工作得最好.
  • 同样地, 如果代码的读者或维护者只有很小的概率使用不同的语言, 那么不要在标识符里使用 非ASCII 字符.