这章的主题是“抽象”。主要内容大概包括如何将语句组织成函数。有了函数以后就不必反反复复向计算机传递同样的指令了。还会介绍参数、作用域,递归的概念及其在程序中的用途。
观点
- 程序应该是非常抽象的,就像“下载网页、计算频率、打印每个单词的频率”一样易懂。虽然没有明确的说明它是怎么做的,但代码读完就知道程序做什么了。具体的操作细节会在其他地方写出——在独立的函数定义中。
- 编写函数只是给程序需要的部分(也可能是其他程序)提供服务,能保证函数在被提供可接受参数的时候工作正常,参数错误的话显然会导致失败。(这时候要用断言和异常)
知识点
- 在函数内为参数赋值不会改变外部任何变量的值
- 字符串(以及数字和元组)是不可变的,即无法被修改。
- 当参数是一个列表的时候,修改这个列表,会影响到外部的变量
- 函数只能修改参数对象本身,如果参数不可变,应该从函数中返回需要的值,如果值多于一个以元组的形式返回
创建函数
使用下面的代码:
def hello(name):
return 'Hello, ' + name + '!'
>>> print hello('world')
Hello, world!
>>> print hello('Gumby')
Hello, Gumby!
记录函数
如果在函数的开头写下字符串,他就会作为函数的一部分进行存储,这称为文档字符串。
使用下面的代码:
>>> def square(x):
... 'Calculates the square of the number x.'
... return x*x
...
>>> square.__doc__
'Calculates the square of the number x.'
内建的help函数是非常有用的。使用下面的代码:
>>> help(square)
Help on function square in module __main__:
square(x)
Calculates the square of the number x.
所有的函数都返回了东西,当不需要它们返回值的时候,它们就返回None
函数的参数
关键字参数
有时候,参数的顺序是很难记住的,为了让事情简单些,可以提供参数的名字。
使用下面的代码:
>>> def hello_1(greeting,name):
... print ('%s, %s!'%(greeting,name))
...
>>> hello_1(greeting="Hello",name="world")
Hello, world!
这类使用参数名提供的参数叫做关键字参数。每个参赛的含义变得更加清晰,而且就算弄乱了参数的顺序,对于程序的功能也没有任何影响。
而且关键字参数在函数中给参数提供默认值。
收集参数
有些时候让用户提供任意数量的参数是很有用的。这其实不难。
使用下面的代码:
>>> def print_params(*params):
... print params
...
>>> print_params('Testing')
('Testing',)
>>>
>>> print_params('Testing','param2')
('Testing', 'param2')
>>>
>>> print_params(1,2,3)
(1, 2, 3)
将关键词参数和收集参数结合起来,这一部分觉得没什么用,先跳过了。
参数的作用域
这一部分也跳过了。
只说一点,如果在一个函数内部要使用全局变量,需要用到global进行声明。使用下面的代码:
>>> x = 1
>>> def change_global():
... global x
... x = x+1
...
>>> change_global()
>>> x
2
递归
这部分也跳过了