Python之函数式编程(二)
1.返回函数
(1)一个函数可以返回一个计算结果,也可以返回一个函数。
(2)返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。
2.匿名函数
(1)关键字lambda
表示匿名函数,匿名函数主要用来简化代码和避免函数名冲突。
说明:关键字lambda
表示匿名函数,冒号前面的x
表示函数参数。匿名函数有个限制,就是只能有一个表达式,不用写return
,返回值就是该表达式的结果。
eg:
def f(x):
return x * x
#以上等价于
lambda x: x * x
(2)可以把匿名函数赋值给一个变量,再利用变量来调用该函数.
eg:
f = lambda x: x * x
f(5)
结果:25
(3)可以把匿名函数作为返回值返回
eg:
def build(x, y):
return lambda: x * x + y * y
注意:整个匿名函数才可以赋值给遍量,而不是lambda
3.闭包
闭包,顾名思义,就是一个封闭的包裹,里面包裹着自由变量,就像在类里面定义的属性值一样,自由变量的可见范围随同包裹,哪里可以访问到这个包裹,哪里就可以访问到这个自由变量。
闭包首先要定义一个嵌套函数,并且外面的函数返回内部函数的函数名,见下面例子:
def nth_power(exponent):
def exponent_of(base):
return base ** exponent
return exponent_of # 返回值是 exponent_of 函数
square = nth_power(2)
cube = square(3)
print(cube) # 9
这里的 square
就是一个闭包,闭包本质上是一个函数,它有两部分组成,内部函数和外部函数与内部函数之间的变量。这里为exponent_of
函数和变量 exponent
。闭包使得这些变量的值始终保存在内存中。
3.装饰器
说明:使用装饰器是为了不更改原来函数的定义的情况下,对该函数的功能进行扩展。这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
语法:先定义一个装饰器函数,假设为outer()
,然后在所要装饰的函数的定义前一行加上@ + 装饰函数名字
,这里为@outer
知识补充:函数是一个对象,函数对象可以赋值给一个变量,所以,通过变量也能调用该函数。但是,函数对象有一个__name__
属性,可以拿到函数的名字,就是拿到该变量现在所指向的函数对象的名字。
eg:
def a(): #定义该函数,做了两件事,1.函数名为a永远不会变 2.定义了一个变量a,并且a指向该函数
pass
len = abs #len变量指向abs()函数
print(len(-30)) #指向函数的变量可以调用其所指向的函数对象
abs = a #变量abs指向a()函数
print(len.__name__) #__name__属性可以获得该变量所指向的函数的函数名
print(abs.__name__)
结果:
30
abs
a
(1)装饰函数为内嵌函数(用的很多,基本上用这种模式)
eg:
def outer(func):
def inner():
print('参数func所指向的函数为{}'.format(func.__name__))
print('欢迎进入数据库!')
func()
print('断开数据库,再见!')
print('参数func所指向的函数为{}'.format(func.__name__))
return
return inner
@outer
def myfunc():
print('正在处理数据')
myfunc()
结果:
参数func所指向的函数为myfunc
欢迎进入数据库!
正在处理数据
断开数据库,再见!
参数func所指向的函数为myfunc
解释一下,装饰器的运行过程:
①把myfunc
作为参数,传入装饰函数outer()
中,此时,myfunc
、func
同时指向func()
函数
②执行outer()
函数。执行outer()
函数时,遇到函数inner()
,先将inner()
函数,读入内存中(不执行,函数是被调用的时候才执行),返回函数inner()
③此时,myfunc
= inner
,也就是,myfunc、inner
同时指向inner()
函数
④myfunc()
语句,myfunc
指向的是inner()
函数,所以,该语句是调用inner()
函数
注意:内嵌函数都可以调用内嵌该函数的“外部变量”,所以,这里,inner()函数中可以用func变量.
(2)装饰函数不为内嵌函数(用的很少,基本不用)
eg:
def outer(func):
print('参数func所指向的函数为{}'.format(func.__name__))
print('欢迎进入数据库!')
func()
print('断开数据库,再见!')
print('参数func所指向的函数为{}'.format(func.__name__))
return func
@outer
def myfunc():
print('正在处理数据')
myfunc()
结果:
参数func所指向的函数为myfunc
欢迎进入数据库!
正在处理数据
断开数据库,再见!
参数func所指向的函数为myfunc
正在处理数据
逻辑有点不对,我只是想表面这样是可以实现的。
(3)对带参数的函数进行装饰
eg:
def outer(func):
def inter(name, thing):
print('欢迎进入数据库!')
func(name, thing)
print('断开数据库,再见!')
return
return inter
@outer
def myfunc(name, thing):
print('{}正在使用数据库处理{}'.format(name, thing))
myfunc('wang', 'web')
结果:
欢迎进入数据库!
wang正在使用数据库处理web
断开数据库,再见!
(4)对参数数量不确定的函数进行装饰
eg:
def outer(func):
def inter(*args, **kw):
return func(*args, **kw)
return inter
@outer
def myfunc(*args, **kw):
print(args)
print(kw)
return args[0]
a = myfunc(1, 2, 3, city='Beijing')
print(a)
结果:
(1, 2, 3)
{'city': 'Beijing'}
1
(5)让装饰器带参数
说明:就是先执行带参数的装饰函数,将返回值所指向的函数再装饰函数
eg:
def tt(name):
print('我是{}'.format(name))
def outer(func):
def inter(*args, **kw):
return func(*args, **kw)
return inter
return outer #注意这里应该返回装饰器
@tt('wanghao')
def myfunc(*args, **kw):
print(args)
print(kw)
return args[0]
a = myfunc(1, 2, 3, city='Beijing')
print(a)
结果:
我是wanghao
(1, 2, 3)
{'city': 'Beijing'}
1
解释:
①先执行函数tt()
:执行print('我是{}'.format(name))
语句,然后,读取函数outer()
到内存中,返回outer
②用@outer
来装饰函数myfunc()
(6)多个装饰器装饰同一个函数
说明:装饰器是从下往上执行的,(先贴近函数的装饰器先执行)
eg:
def decorator_a(func):
print('Get in decorator_a')
def inner_a(*args, **kwargs):
print('Get in inner_a')
return func(*args, **kwargs)
return inner_a
def decorator_b(func):
print('Get in decorator_b')
def inner_b(*args, **kwargs):
print('Get in inner_b')
return func(*args, **kwargs)
return inner_b
@decorator_b
@decorator_a
def f(x):
print('Get in f')
return x * 2
f(1)
结果:
Get in decorator_a
Get in decorator_b
Get in inner_b
Get in inner_a
Get in f
解释:依次执行decorator_a()
,decorator_b()
,inner_b()
,inner_a()
,有点先从下到上,再从上到下的感觉。(实际执行过程只有从下到上,是指针的传递让我们感觉后面又从上到下)
再举一个例子:
eg:
def outer1(func):
def inter1(name, thing):
print('您好!')
print('正在连接数据库')
func(name, thing)
return inter1
def outer2(func):
def inter2(name, thing):
func(name, thing)
print('正在断开数据库')
print('再见!')
return
return inter2
@outer2
@outer1
def f(name, thing):
print('{}正在做{}'.format(name, thing))
f('wanghao', 'shi')
结果:
您好!
正在连接数据库
wanghao正在做shi
正在断开数据库
再见!
4.偏函数
说明:当函数的参数个数太多,需要简化时,使用functools.partial
可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,即修改函数的默认值,从而在调用时更简单。
eg:
import functools
#int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做N进制的转换:
print(int('1000'))
int2 = functools.partial(int, base = 2)
print(int2('1000'))
#结果:
1000
8
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/84817.html