python -- 函数以及函数式编程
2017-09-05 21:29
399 查看
函数以及函数式编程
到目前为止,我们的Python 代码已经实现了小的分块。它们都适合处理微小任务,
但是我们想复用这些代码,所以需要把大型代码织成可管理的代码段。代码复用的第一步是使用函数,它是命名的用于区分的代码段。函数可以接受任何数字或者其他类型的输入作为参
数,并且返回数字或者其他类型的结果。
定义一个函数
为了定义Python 函数,你可以依次输入def、函数名、带有函数参数的圆括号,最后紧跟一个
冒号(:)。函数命名规范和变量命名一样(必须使用字母或者下划线_ 开头,仅能含有字母、数字和下划线)。
我们先定义和调用一个没有参数的函数。下面的例子是最简单的Python 函数:
>>> def do_nothing(): ... pass
定义一个无参数函数
现在,定义一个无参数,但打印输出一个单
词的函数:>>> def make_a_sound(): ... print('momoda') ... >>> make_a_sound() momoda >>> def agree(): ... return True ... #或者,调用这个函数,使用if 语句检查它的返回值: >>> if agree(): ... print("Is true") ... else: ... print("Is Flase") ... Is true
定义一个有参函数
>>> def echo(str): ... return str*2 ... >>> echo('abc') 'abcabc' >>> def fruit_color(color): if color == 'red': print('这可能是一个苹果,或者是西红柿') elif color == 'yellow': print('这或许是一个香蕉也说不定') elif color == 'blue': print('一定是蓝莓吧') else: print('我可猜不到这是什么') fruit_color('red')
位置参数
下面创建一个带有位置参数的函数,并且返回一个字典:
def menu(a,b,c): return {'a':a,'b':b,'c':c} print(menu('a','b','c’)) {'a': 'a', 'b': 'b', 'c': 'c’} #尽管这种方式很常见,但是位置参数的一个弊端是必须熟记每个位置的参数的含义。在调 #用函数menu() 时误把最后一个参数当作第一个参数,会得到完全不同的结果: print(menu('c','b','a')) {'c': 'a', 'b': 'b', 'a': 'c'}
关键字参数
为了避免位置参数带来的混乱,调用参数时可以指定对应参数的名字,甚至可以采用与函
数定义不同的顺序调用:def menu(a,b,c): return {'a':a,'b':b,'c':c} print(menu(c='c',b='b',a='a’)) 当然也可以混合使用 def menu(a,b,c): return {'a':a,'b':b,'c':c} print(menu(a='a',c='c',b='b'))。
指定默认参数值
举例:
def menu(a,b,c): return {'a':a,'b':b,'c':c} print(menu(c='b',b='a’))
报错,缺少参数,实际上我们可以设置参数默认值
def menu(a='a',b='b',c='c'): return {'a':a,'b':b,'c':c} print(menu(c='b',b='a’)) print(menu())
使用*收集位置参数
当参数被用在函数内部时, 星号将一组可变数量的位置参数集合成参数值的元组。
def my_print(*Str): print(Str) my_print() () my_print(1,2,3,4,5): (1, 2, 3, 4, 5) my_print(1,2,3,'let\'s go’) (1, 2, 3, "let's go")
使用两个星号可以将参数收集到一个字典中,参数的名字是字典的键,对应参数的值是字
典的值。下面的例子定义了函数print_kwargs(),然后打印输出它的关键字参数:def my_print(**abc): print(abc) my_print(a='a',b='b',c='c')
函数本身也是一个对象
之前提过Python 中一切都是对象,包括数字、字符串、元组、列表、字典和函数。函数是Python 中的一等公民,可以把它们(返回值)赋给变量,可以作为参 数被其他函数调用,也可以从其他函数中返回值。它可以帮助你在Python 中实现其 他语言难以实现的功能。
#为了测试,现在定义一个简单的函数answer(),它没有任何参数,仅仅打印输出数字42: >>> def answer(): ... print(42) #运行该函数,会得到下面的结果: >>> answer() 42 #再定义一个函数run_something。它有一个参数func,这个参数是一个可以运行的函数的名字: >>> def run_something(func): ... func() #将参数answer 传到该函数,在这里像之前碰到的一样,把函数名当作数据使用: >>> run_something(answer) 42 ######################################## #我们来运行一个带参数的例子。定义函数add_args(),它会打印输出两个数值参数(arg1和arg2)的和: >>> def add_args(arg1, arg2): ... print(arg1 + arg2) #那么,add_args() 的类型是什么? >>> type(add_args) <class 'function'> #此刻定义一个函数run_something_with_args(),它带有三个参数: #• func——可以运行的函数 #• arg1——func 函数的第一个参数 #• arg2——func 函数的第二个参数 >>> def run_something_with_args(func, arg1,arg2): add_args(arg1, arg2) >>> run_something_with_args(add_args, 5, 9) 14
内部函数
内部函数可以看作一个闭包。闭包是一个可以由另一个函数动态生成的函数,并且可以改变和存储函数外创建的变量的值。
>>> def outer(a, b): ... def inner(c, d): ... return c + d ... return inner(a, b) ... >>> >>> outer(4, 7) 11 ######################### def fun5(): def sayhello(name): print("hello ", name) return sayhello #返回的是函数名称 fun5()("zhangsan")
匿名函数:lambda()函数
edit_story(stairs, lambda word: word.capitalize() + '!')
map
map(funcname, list)
map(function, sequence[, sequence, …]) -> list:将function作用于给定序列的每一个元素,
并将结果作为list返回;如果函数中需要多个参数则从多个序列中读取(python3里面,map()的返回值已经不再是list,而是iterators, 所以想要使用,只用将iterator 转换成list 即可)
def square(x): return x**2 map(square, [1,2,3,4,5]) f1 = lambda x:x**2 #lambda表达式就是一个匿名函数 print(f1(3)) i1 = map(f1, [1,2,3,4,5]) print(list(i1))
reduce
reduce(function, sequence[, initial]) -> value:与map相比 , reduce类似于一个聚合类的
应用方法, 把list中的参数, 依次传递给funcname, 每次funcname的参数都是上个funcname执行结果和下一个list中的元素, 所以, funcname 的 参数必须是两个. 从执行过程看, 有点像递
归.如果指定了initial则首先从此值和第一个元素开始计算。
def sum(x,y): return x+y print(functools.reduce(sum, [1, 2, 3, 4, 5])) print(functools.reduce(lambda x,y:x+y, [1,2,3,4,5])) print(functools.reduce(lambda x,y:max([x,y]), [1,2,3,4,5]))
filter()
filter(function or None, sequence) -> list,tuple,string:
调用一个布尔类型的函数来迭代遍历每个seq中的元素,返回使得func返回为true的
元素的序列。print(list(filter(lambda x:isinstance(x, (int)), [1,2,"3"]))) print(list(filter(lambda x:x>2, [1,2,3])))
sorted
sorted( list, [comp_func])
排序方法, 第二个是可选参数, 根据可选参数返回的值, 对结果进行排序, comp_func
接受两个参数(x, y), 最终返回的结果应该是-1.0,1, 如果返回的是-1, 表示x , 0表示x=y,1表示x>y, 所以, 实际的排序可以自定义
print(sorted([4,6,1,2,3])) print(sorted([4,6,1,2,3], reverse=True)) print(sorted([1,2,3,4,5,6],key=cmp_to_key(lambda x,y:y-x)))
命名空间和作用域
一个名称在不同的使用情况下可能指代不同的事物。Python 程序有各种各样
的命名空间,它指的是在该程序段内一个特定的名称是独一无二的,它和其他同名的命名空间是无关的。每一个函数定义自己的命名空间。如果在主程序(main)中定义
一个变量x,在另外一个函数中也定义x 变量,两者指代的是不同的变量。
每个程序的主要部分定义了全局命名空间。因此,在这个命名空间的变量是
全局变量。animal = 'cat' >>> def print_global(): . . . print('inside print_global:',animal) . . . >>> print('outside print_global:',animal) outside print_global: cat >>> print_global() inside print_global: cat #################### #在函数中改变全局变量,会报错: >>> def change_and_print_global(): ... print('insid change_and_print_global:',animal) ... animal = 'dog' ... print('after the change:',animal) ... >>> change_and_print_global() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in change_and_print_global UnboundLocalError: local variable 'animal' referenced before assignment
如果在函数中不声明关键字global,Python 会使用局部命名空间,同时变量也是局
部的。函数执行后回到原来的命名空间。Python 提供了两个获取命名空间内容的函数:
• locals() 返回一个局部命名空间内容的字典;
• globals() 返回一个全局命名空间内容的字典。
生成器
生成器是用来创建Python 序列的一个对象。目的就是为了避免一下子生成的数据太多占用大量内存,生成器会在数据被用到时生成数据。
def my_range(first, last, step=1): n = first while n<last: yield n #yield是一个关键字,使用yeild的函数实际上一个生成器 n+=step print(my_range()) #<generator object my_range at 0x0000021FC5AE>
装饰器
参考文章1,参考文章2名称中_和__的用法
以两个下划线__ 开头和结束的名称都是Python 的保留用法。因此,在自定义的变量
中不能使用它们。选择这种命名模式是考虑到开发者一般是不会选择它们作为自己的变量的。
if __name__ == '__main__': print("这里是入口")
相关文章推荐
- Python的函数以及函数式编程
- python 学习笔记---函数式编程之高阶函数
- python浓缩(11)函数和函数式编程
- Learning Python 012 函数式编程 2 返回函数 匿名函数 装饰器 偏函数
- 【python学习笔记】函数式编程:返回函数
- Python入门 第四天(函数式编程、map、reduce、filter、排序函数、函数返回函数、闭包、匿名函数lambda)
- Python学习笔记11:Python函数和函数式编程
- python 函数、函数式编程、变量作用域、函数__doc__属性
- 【Python学习笔记】函数式编程:偏函数
- python函数式编程之匿名函数、装饰器、偏函数
- python lambda函数 与 函数式编程
- python再复习(4)高级特性、函数式编程以及用法小结
- python3 第二十三章 - 函数式编程之Partial function(偏函数)
- 转自:Python函数式编程指南(二):函数
- Python函数式编程之高阶函数
- python3 第二十一章 - 函数式编程之return函数和闭包
- python函数式编程:匿名函数,装饰器,偏函数
- Python进阶学习笔记——函数式编程之高阶函数
- 【语言工具】Python闭包,装饰器,生成器,偏函数,函数式编程,lamda,map,reduce,filter
- python笔记11 - lambda函数,globals()/locals()函数,eval()exec()函数,闭包函数,函数式编程,高阶函数