抽象是隐藏多余细节的艺术,定义处理细节的函数可以让程序更加的抽象。
1、函数定义
函数使用def来定义,函数名后面可以加入参数。函数可以被调用,它执行某种行为,并返回一个值。
内建的callable函数可以用来判断一个函数是否可以被调用。
函数的注释:#,加强对函数的理解
函数的文档字符串:在函数定义的下方写的字符串,它被作为函数的一部分进行存储。有两种方法能够访问,一种是fun.__doc__,一种是help(fun)
函数的返回值:即使函数没有显示地显示return语句,或者return语句为空,函数还是存在默认返回值None的。
2、函数参数
2.1 位置参数(参数的位置很重要)
当传入函数的参数是字符、数字、字符串或元组等不可变数据结构时,参数值无法被修改。如果在函数内部只是对参数进行重绑定(赋值),函数外的变量不会被影响。
如果传入的值是可变的数据结构,如,列表作为参数时,函数内部对参数的修改直接反映到该对象本身。传参过程相当于对列表的一个引用。
函数只能修改参数对象本身。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 >>> def change(n): 2 print n 3 n = 'ddd' 4 print n 5 6 >>> m = 'qqq' 7 >>> change(m) 8 qqq 9 ddd 10 >>> m 11 'qqq' 12 13 14 >>> def change(n): 15 print n 16 n[0] = 'ddd' 17 print n 18 19 >>> v =['fff'] 20 >>> change(v) 21 ['fff'] 22 ['ddd'] 23 >>> v 24 ['ddd']
2.2 关键字参数和默认值
关键字参数就是说在给函数传递参数时,可以为参数起一个名字,并且还可以为此函数参数名提供默认值。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 >>> def hello(greeting = 'Hello',name = 'World'): 2 print '%s, %s' % (greeting, name) 3 4 >>> hello() 5 Hello, World 6 >>> hello('our') 7 our, World 8 >>> hello(name = 'earth') 9 Hello, earth
2.3 收集参数
函数在定义中,通过在参数前加星号,将传递进来的多个参数转化为一个对象,元组或字典,可以说是将这些参数值收集起来。
参数前加一个星号,表明将所有的值放在同一个元组中,该参数的返回值是一个元组。
参数前加两个星号,表明将所有的值放在同一个字典中,该参数的返回值是一个字典。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 >>> def print_param(x, y, z = 3, *pospar, **keypar): 2 print x,y,z 3 print pospar 4 print keypar 5 6 >>> print_param(3,4,5,6,7,8,m = 1,n = 2) 7 3 4 5 8 (6, 7, 8) 9 {'m': 1, 'n': 2}
2.4 反转过程(分配参数)
函数在调用中,通过在参数前加星号,传递的参数必须是元组或字典,能够将其值转化为相应变量的值,这个过程可以看做参数值的分配。
参数前加一个星号,表明将元组值分配给对应的函数参数值。
参数前加两个星号,表明将字典中的值赋给键,函数的定义中要将键作为参数名。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 >>> def add(x,y): 2 print x,y 3 return x + y 4 5 >>> add(*param) 6 1 2 7 3 8 9 >>> def test(name,age): 10 print name,age 11 12 >>> m = {'name':'xiaoli','age':'12'} 13 >>> test(**m) 14 xiaoli 12 15 >>> m = {'name':'xiaoli','age':12} 16 >>> test(**m) 17 xiaoli 12
3、作用域
变量存储在作用域中(也叫命名空间),Python中有两类主要的作用域-全局作用域和局部作用域,作用域可以嵌套。
函数内的变量称为局部变量,函数外的变量称为全局变量。如果全局变量和局部变量有重名,全局变量会被局部变量屏蔽,如果需要的话可以在函数内部使用globals()函数获取全局变量的值,它返回全局变量的一个字典。例如全局变量中有一个param的变量值,可以这样获取:globals()['param']
如何在函数中引用全局变量,重绑定全局变量。采用golobal关键字将局部变量声明为全局变量。
4、有用函数:map、filter、reduce、lambda
map函数将序列中的元素传递给指定函数,并将其返回值转化为一个新的序列。
filter函数可以基于一个返回布尔值的函数对传递的元素进行过滤,返回值为真的将组成一个新的列表。
reduce函数将序列中的前两个元素与给定的函数联合使用,并且将它们的返回值和第3个元素继续联合使用,直到整个序列都处理完毕,返回一个最终的结果。
lambda表达式的特性是创建短小的函数。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 >>> map(str, range(10)) 2 ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] 3 >>> def square(x): 4 return x*x 5 6 >>> map(square, range(10)) 7 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 8 >>> def func(x): 9 return x.isalnum() 10 11 >>> seq = ['foo', 'x23', '?!', '*%2'] 12 >>> filter(func, seq) 13 ['foo', 'x23'] 14 >>> filter(lambda x:x.isalnum(),seq) 15 ['foo', 'x23'] 16 >>> number = range(10) 17 >>> reduce(lambda x,y:x+y, number) 18 45