第5章 模块与函数
5.1 Python 程序的结构
Python 的程序由 包 、模块和函数组成。包 是由一系列模块组成的集合。模块是处理某一类问题的函数和类的集合。
5.2 模块
一个Python文件就是一个模块。
5.2.1 模块的创建
模块由代码、函数或类组成 。
# 自定义模块
def func(): #定义一个函数func()
print "MyModule.func()"
class MyClass: #定义一个类MyClass
def myFunc(self): #在类中定义一个方法myFunc()
print "MyModule.MyClass.myFunc()"
5.2.2 模块的导入
import module_name
from module_name import function_name
同一模块文件支持多条导入,而且import 语句可以置于程序中任意位置,甚至可以放在条件语句中。
5.2.3 模块的属性
python 模块有一些内置属性:
1、 __name__ 用于判断当前模块是否是程序的入口,如果当前程序正在被使用,__name__的值为 “__main__" .
2、 __ doc__ 可以输出文档字符串的内容,即用于描述该对象的作用。
5.2.4 模块的内置函数
1、apply( )
apply() 可以实现调用可变参数列表的函数,把函数的参数存放在一个元组或序列中。 apply() 的 返回值就是 自定义函数 的返回值。
def sum(x=1, y=2):
return x + y
print apply(sum, (1, 3))
输出结果:4
2、filter ( )
filter ( ) 可以对某个序列做过滤处理,对自定义函数的参数返回的结果是否为”真“来过滤,并一次性返回处理结果。filter( )的返回值是由自定义函数的返回值组成的序列,返回的类型与参数 的类型相同。
# filter() 过滤大于0的数字
def func(x):
if x > 0:
return x
print filter(func, range(-9, 10))
输出结果:[1,2,3,4,5,6,7,8,9,]
注:filter()中的过滤函数func()的参数不能为空,否则,没有可以存储sequence元素的变量,func()也不能处理过滤。
3、reduce ( )
reduce ( ) 可以在函数 func( ) 中实现对参数sequence 的连续操作。
reduce (func , sequence [ , initial ] ) 参数initial 的值将首先传入 func ()进行计算,如果sequence 为空,则对 initial 的值进行处理。
# reduce()
def sum(x, y):
return x + y
print reduce(sum, range(0, 10)) #输出结果:45</span>
print reduce(sum, range(0, 10), 10) #输出结果:55
print reduce(sum, range(0, 0), 10) # 10
4、map()
map ( ) 可以对多个序列的每个元素执行相同的操作,并组成列表返回。第4章用它来作 解包 。
# map() 实现列表中数字的幂运算
def power(x): return x ** x
print map(power, range(1, 5)) # [1,4,27,256]
def power2(x, y): return x ** y # [1, 16, 27, 16]
print map(power2, range(1, 5), range(5, 1, -1))
注:如果序列的长度不同,则短的序列补充”none",再进行计算,none无类型,会出错。
5.2.5 自定义包
包就是一个至少包含__init__ . py 文件的文件夹。把实现一个常用功能的代码组合到一个包中,调用包提供的服务从而实现重用。
5.3 函数
5.3.1 函数的定义
1、函数不能以数学开头。2、函数放在一对圆括号中。3、实参与形参的对应关系。
5.3.2 函数的参数
1、Python 通过名字邦定的机制,把实际参数的值 和形式参数的名称邦定在一块,即形参与实参指向内存中的同一个存储空间。
2、在程序开发过程中,常常需要传递可变长度的参数。在函数的参数前使用标识符 * 可以实现这个要求。
# 传递可变参数
def func(*args):
print args
func(1, 2, 3) #传入的实际参数被打包到一个元组中,输出结果:(1,2,3)
3、标识符 ** 放在参数前面可以引用一个字典,根据实际参数的赋值表达式生成字典。注意: * 必须写在 ** 前面
def search(*t, **d): # *t 对应"one","three" 组成一个元组 **d 对应后面的生成一个字典
keys = d.keys()
values = d.values()
print keys # ['three', 'two', 'one']
print values # ['3', '2', '1']
for arg in t:
for key in keys:
if arg == key:
print "find:",d[key] #输出:find: 1
find: 3
search("one", "three", one="1",two="2",three="3")
5.5.3 函数的返回值
1、 函数的返回使用return 语句 ,return 后面可以是变量或表达式。
2、如果函数没有返回值,则输出 None . None是python中的一个对象,不属于数字也不属于字符串。
def func(x, y, z):
l = [x, y, z]
l.reverse()
a, b, c = tuple(l)
return a, b, c
x, y, z = func(0, 1, 2)
print x, y, z
5.3.4 函数的嵌套
函数的嵌套层数不宜过多,否则容易造成代码可读性差,最好控制在3层以内为好。
5.3.5 递归函数
递归函数是函数主体内直接或间接地调用自己,即函数的嵌套是函数本身。分为两个过程:第一阶段,递归函数内部调用自己。第二阶段,递归函数从后往前返回。
# 计算阶乘
def refunc(n):
i = 1
if n > 1: # 递归的结束判断
i = n
n = n * refunc(n-1) # 递推
print "%d! =" %i, n
return n # 回归
refunc(5)
# 使用reduce计算阶乘
print "5! =", reduce(lambda x, y: x * y, range(1, 6))
5.3.6 lambda 函数
lambda 函数用于创建一个匿名函数,lambda 也称为表达式,它只能使用表达式,不能使用判断、循环等多重语句。
格式 : lambda 变量1 , 变量2 , ...... :表达式
# lambda
def func():
x = 1
y = 2
m = 3
n = 4
sum = lambda x, y : x + y
print sum
sub = lambda m, n : m - n
print sub
return sum(x, y) * sub(m, n)
print func()
5.3.7 Generator 函数
生成器(Generator)的作用是一次生产一个数据项,并把数据项输出。一般放在for循环中遍历,
函数内使用yield 生成数据,
通过 next ( ) 方法获得生成的数据项。
# 定义Generator函数
def func(n):
for i in range(n):
yield i
# 在for循环中输出
for i in func(3):
print i
# 使用next()输出
r = func(3) #把func ( ) 赋值给列表 r
print r.next()
print r.next()
print r.next()<strong></strong>
</pre><pre name="code" class="python">第6行 输出结果:0
1
2
10-12行 输出结果:同上
</pre><pre name="code" class="python"># yield与return区别 yield 生成值并不会中止程序的执行,返回值后程序继续往后执行。return 返回值后,程序将中止执行。
def func(n):
for i in range(n):
return i
def func2(n):
for i in range(n):
yield i
print func(3)
f = func2(3)
print f
print f.next()
print f.next()
Generator 函数可以返回元素的值,而序列也可以获取元素的值。但两者还是有区别:Generator 函数一次只返回一个数据项,占用内存少;当访问越界时,Generator 函数会报错 StopIteration。序列一次返回所有的数据,元素的访问是通过索引来实现。当访问越界时,序列提示 list index out of range 错误。
当程序需要较高的性能或一次只需要一个值进行处理时,使用Generator 函数。当需要获取一次性一组元素的值时,使用序列。