fibs = [0, 1]
for i in range(8):
fibs.append(fibs[-2] + fibs[-1])
实际上,斐波那契 数的计算是以抽象的方式完成的:你只是让计算机这样做,而没有具体地告诉它如何做。你创建 了一个名为fibs的函数,并在需要计算斐波那契数时调用它。如果需要在多个地方计算斐波那契 数,这样做可节省很多精力。
抽象可节省人力,但实际上还有个更重要的优点:抽象是程序能够被人理解的关键所在。
函数执行特定的操作并返回一个值,可以调用它(调用时可能需要提供一些参数——放在圆括号中的内容)。一般而言,要判断某个对象是否可调用,可使用内置函数callable。
>>> import math
>>> x=1
>>> y=math.sqrt
>>> callable(x)
False
>>> callable(y)
True
定义函数时用 def 语句
>>> def hello(name):
return 'Hello, '+ name +'!'
>>> print(hello('world'))
Hello, world!
>>> print(hello('Gumby'))
Hello, Gumby!
参数的收集:
当需要有 任意个参数时可以用 *
首先定义一个函数:
>>> def print_params(*params):
print(params)
指定一个参数:
>>> print_params('Testing')
('Testing',)
此时打印结果为一个元组,将任意个数的参数存与元组中
指定多个参数:
>>> print_params(1,2,3)
(1, 2, 3)
当要收集关键字参数,可使用两个星号
>>> def print_param_3(**params):
print(params)
>>> print_param_3(x=1,y=2,z=3)
{'x': 1, 'y': 2, 'z': 3}
这样得到的是一个字典。
参数的分配:
>>>#定义函数add包含两个参数
>>> def add(x,y):
return x + y
>>>#定义元组params
>>> params =(1,2)
>>> #函数add调用多个参数时,使用*
>>> add(*params)
3
变量到底是什么呢?可将其视为指向值的名称。因此,执行赋值语句x = 1后,名称x指向值 1。这几乎与使用字典时一样(字典中的键指向值),只是你使用的是“看不见”的字典。这种“看不见的字典”称为命名空间或作用域。
>>> def foo():
x = 42
>>> x = 1
>>> foo()
>>> x
1
在这里,函数foo修改(重新关联)了变量x,但当你终查看时,它根本没变。这是因为调 用foo时创建了一个新的命名空间,供foo中的代码块使用。赋值语句x = 42是在这个内部作用域 (局部命名空间)中执行的,不影响外部(全局)作用域内的x。在函数内使用的变量称为局部变 量(与之相对的是全局变量)。参数类似于局部变量,因此参数与全局变量同名不会有任何问题。
简单地说,递归意味着引用(这 里是调用自身)。
下面是一个常见的递归定义:
递归式定义(包括递归式函数定义)引用了当前定义的术语。
下面是一个递归式函数定义:
def recursion():
return recursion()
这个函数中的递归称为无穷递归(就像以while True打头且不包含break和return语句的循环 被称为无限循环一样),因为它从理论上说永远不会结束。
递归函数通常包含下面两部分。
基线条件(针对小的问题):满足这种条件时函数将直接返回一个值。
递归条件:包含一个或多个调用,这些调用旨在解决问题的一部分。
这里的关键是,通过将问题分解为较小的部分,可避免递归没完没了,因为问题终将被分解成基线条件可以解决的小问题。
经典案例1:阶乘
>>> def factorial(n):
result = n
for i in range(1,n):
result *=i
return result
下面来考虑如何使用函数来实现这个定义。理解这个定义后,实现起来其实非常简单。
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)
这是前述定义的直接实现