您的位置:首页 > 编程语言 > Python开发

Python日志8/1

2017-08-01 21:06 176 查看
一、抽象

抽象是数学中非常常见的概念。举个例子:

计算数列的和,比如:
1 + 2 + 3 + ... + 100
,写起来十分不方便,于是数学家发明了求和符号∑,可以把
1
+ 2 + 3 + ... + 100
记作:

100

∑n

n=1

这种抽象记法非常强大,因为我们看到∑就可以理解成求和,而不是还原成低级的加法运算。

而且,这种抽象记法是可扩展的,比如:

100

∑(n2+1)

n=1

还原成加法运算就变成了:

(1 x 1 + 1) + (2 x 2 + 1) + (3 x 3 + 1) + ... + (100 x 100 + 1)

可见,借助抽象,我们才能不关心底层的具体计算过程,而直接在更高的层次上思考问题。

写计算机程序也是一样,函数就是最基本的一种代码抽象的方式。
二、函数

(1)定义函数

要使用
def
语句,依次写出函数名、括号、括号中的参数和冒号
:
,然后,在缩进块中编写函数体,函数的返回值用
return
语句返回。

在Python中,定义一个函数:

def my_abs(x):
if x >= 0:
return x
else:
return -x


如果没有
return
语句,函数执行完毕后也会返回结果,只是结果为
None
return
None
可以简写为
return

定义一个空函数:
def nop():
pass

实际上
pass
可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个
pass
,让代码能运行起来。缺了pass就会报错。

(2)参数检查

数据类型检查可以用内置函数
isinstance
实现,比如下面的my_abs函数定义:

def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x


定义函数时,需要确定函数名和参数个数;

如果有必要,可以先对参数的数据类型做检查;

函数可以同时返回多个值,但其实就是一个tuple。

先定义一个函数,传入一个list,添加一个
END
再返回:
def add_end(L=[]):
L.append('END')
return L


当你正常调用时,结果似乎不错:
>>> add_end([1, 2, 3])
[1, 2, 3, 'END']
>>> add_end(['x', 'y', 'z'])
['x', 'y', 'z', 'END']


当你使用默认参数调用时,一开始结果也是对的:
>>> add_end()
['END']


但是,再次调用
add_end()
时,结果就不对了:
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']


很多初学者很疑惑,默认参数是
[]
,但是函数似乎每次都“记住了”上次添加了
'END'
后的list。

原因解释如下:

Python函数在定义的时候,默认参数
L
的值就被计算出来了,即
[]
,因为默认参数
L
也是一个变量,它指向对象
[]
,每次调用该函数,如果改变了
L
的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的
[]
了。

所以,定义默认参数要牢记一点:默认参数必须指向不变对象!


可变参数

在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。

我们以数学题为例子,给定一组数字a,b,c……,请计算a2 + b2 + c2
+ ……。

要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum


但是调用的时候,需要先组装出一个list或tuple:
>>> calc([1, 2, 3])
14
>>> calc((1, 3, 5, 7))
84


如果利用可变参数,调用函数的方式可以简化成这样:
>>> calc(1, 2, 3)
14
>>> calc(1, 3, 5, 7)
84


所以,我们把函数的参数改为可变参数:
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum



关键字参数

关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:
def person(name, age, **kw):
print 'name:', name, 'age:', age, 'other:', kw


函数
person
除了必选参数
name
age
外,还接受关键字参数
kw
。在调用该函数时,可以只传入必选参数:
>>> person('Michael', 30)
name: Michael age: 30 other: {}


参数组合

在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。

比如定义一个函数,包含上述4种参数:
def func(a, b, c=0, *args, **kw):
print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw


要注意定义可变参数和关键字参数的语法:

*args
是可变参数,args接收的是一个tuple;

**kw
是关键字参数,kw接收的是一个dict。

递归函数

在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。栈空间有限,因此会造成栈溢出。使用尾递归(每次调用都是本栈空间的函数,所以只占用一个栈空间)可以防止栈溢出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: