print \ * 40
keys = sorted(keywords.keys()) for kw in keys:
print kw, \, keywords[kw] 它可以像这样调用:
cheeseshop(\, \, \, shopkeeper='Michael Palin', client=\,
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() 方法的结果进行排序,生成了关键字参数名的列表;如果不这样做,打印出来的参数的顺序是未定义的。
4.7.3. 可变参数列表
最后,一个最不常用的选择是可以让函数调用可变个数的参数。这些参数被包装进一个元组(参见 元组和序列 )。在这些可变个数的参数之前,可以有零到多个普通的参数:
def write_multiple_items(file, separator, *args): file.write(separator.join(args))
4.7.4. 参数列表的分拆
另有一种相反的情况: 当你要传递的参数已经是一个列表,但要调用的函数却接受分开一个个的参数值。这时候你要把已有的列表拆开来。例如内建函数 range() 需要独立的 start ,stop 参数。 你可以在调用函数时加一个 * 操作符来自动把参数列表拆开:
>>> 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 \, action,
... print \, voltage, \, ... print \, state, \ ...
>>> d = {\: \, \: \demised\, \: \} >>> 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
上面的示例使用 lambda 表达式返回一个函数。另一个用途是将一个小函数作为参数传递:
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')] >>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
4.7.6. 文档字符串
这里介绍的文档字符串的概念和格式。
第一行应该是关于对象用途的简介。简短起见,不用明确的陈述对象名或类型,因为它们可以从别的途径了解到(除非这个名字碰巧就是描述这个函数操作的动词)。这一行应该以大写字母开头,以句号结尾。
如果文档字符串有多行,第二行应该空出来,与接下来的详细描述明确分隔。接下来的文档应该有一或多段描述对象的调用约定、边界效应等。
Python 的解释器不会从多行的文档字符串中去除缩进,所以必要的时候应当自己清除缩进。这符合通常的习惯。第一行之后的第一个非空行决定了整个文档的缩进格式。(我们不用第一行是因为它通常紧靠着起始的引号,缩进格式显示的不清楚)留白‖相当于‖是字符串的起始缩进。每一行都不应该有缩进,如果有缩进的话,所有的留白都应该清除掉。留白的长度应当等于扩展制表符的宽度(通常是8个空格)。
以下是一个多行文档字符串的示例:
>>> def my_function():
... \ ...
... 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.8. 插曲:编码风格
此时你已经可以写一个更长更复杂的 Python 程序,是时候讨论一下 编码风格 了。大多数语言可以写 (或者更明白地说,格式化 ) 作几种不同的风格。有些
比其它的更好读。让你的代码对别人更易读是个好想法,养成良好的编码风格对此很有帮助。
对于 Python, PEP 8 引入了大多数项目遵循的风格指导。它给出了一个高度可读,视觉友好的编码风格。每个 Python 开发者都应该读一下,大多数要点都会对你有帮助:
?
使用 4 空格缩进,而非 TAB。
在小缩进(可以嵌套更深)和大缩进(更易读)之间,4 空格是一个很好的折中。TAB 引发了一些混乱,最好弃用。
? 折行以确保其不会超过 79 个字符。
这有助于小显示器用户阅读,也可以让大显示器能并排显示几个代码文件。
? ? ? ?
4)。
使用空行分隔函数和类,以及函数中的大块代码。 可能的话,注释独占一行 使用文档字符串
把空格放到操作符两边,以及逗号后面,但是括号里侧不加空格:a = f(1, 2) + g(3, ? 统一函数和类命名。
推荐类名用 驼峰命名,函数和方法名用 小写_和_下划线。总是用 self 作为方法的第一个参数(关于类和方法的知识详见 初识类)。
? 不要使用花哨的编码,如果你的代码的目的是要在国际化 环境。Python 的默认情
况下,UTF-8,甚至普通的 ASCII 总是工作的最好。
? 同样,也不要使用非 ASCII 字符的标识符,除非是不同语种的会阅读或者维护代码。
Footnotes
[实际上,引用对象调用 描述的更为准确。如果传入一个可变对像,调用者会看到调用操1作带来的任何变化(如子项插入到列表中)。 ]5. 数据结构
本章详细讨论了你已经学过的一些知识,同样也添加了一些新内容。
5.1. 关于列表更多的内容
Python 的列表数据类型包含更多的方法。这里是所有的列表对象方法:
list.append(x)
把一个元素添加到链表的结尾,相当于 a[len(a):] = [x]。
list.extend(L)
将一个给定列表中的所有元素都添加到另一个列表中,相当于 a[len(a):] = L。
list.insert(i, x)
在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个链表之前,而 a.insert(len(a), x) 相当于
a.append(x)。
list.remove(x)
删除链表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。
list.pop([i])
从链表的指定位置删除元素,并将其返回。如果没有指定索引,a.pop() 返回最后一个元素。元素随即从链表中被删除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。)
list.index(x)
返回链表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。
list.count(x)
返回 x 在链表中出现的次数。
list.sort(cmp=None, key=None, reverse=False)
对链表中的元素就地进行排序(参数可以用来自定义排序方法,参考 sorted() 的更详细的解释)。
list.reverse() 就地倒排链表中的元素。
下面这个示例演示了链表的大部分方法:
>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print a.count(333), a.count(66.25), a.count('x') 2 1 0
>>> a.insert(2, -1) >>> a.append(333)