python——函数式编程——返回函数篇
1:返回函数
- 一个函数可以返回一个计算结果,也可以返回一个函数。
- 返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。
2:匿名函数
- 关键字
lambda
表示匿名函数,冒号前面的x
表示函数参数(例:lambda x: x * x
) - 匿名函数有个限制,就是只能有一个表达式,不用写
return
,返回值就是该表达式的结果。 - 匿名函数有个好处,因为没有名字,不必担心函数名冲突。匿名函数是一个函数对象,可以把匿名函数赋值给一个变量,再利用变量来调用该函数。
3:装饰器
- 这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。本质上,decorator就是一个返回函数的高阶函数。
- 函数对象有一个
__name__
属性,可以拿到函数的名字。 - 在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。
# 请编写一个decorator,能在函数调用的前后打印出'begin call'和'end call'的日志。
import functools
def log(func):
@functools.wraps(func) # wrap '__name__'
def wrapper(*args, **kw):
print("begin call [%s]" % (func.__name__))
func_tmp = func(*args, **kw)
print("end call [%s]" % (func.__name__))
return func_tmp
return wrapper
@log # 借助Python的@语法,把decorator置于函数的定义处
def hello():
print("hello")
hello()
结果:
begin call [hello]
hello
end call [hello]
>>>
'''思考一下能否写出一个@log的decorator,使它既支持:@log
def f():
pass
又支持:@log('execute')
def f():
pass '''
import functools
def log(text):
def decorator(func):
@functools.wraps(func) # wrap '__name__'
def wrapper(*args, **kw):
if (None != text):
print("[%s]begin call [%s]" % (text, func.__name__))
func_tmp = func(*args, **kw)
print("[%s]end call [%s]" % (text, func.__name__))
else:
print("begin call [%s]" % (func.__name__))
func_tmp = func(*args, **kw)
print("end call [%s]" % (func.__name__))
return func_tmp
return wrapper
if isinstance(text, str):
return decorator
else:
strtmp = text
text = None
return decorator(strtmp)
@log
def hello():
print("hello")
hello()
@log('>>>world')
def hello():
print("hello")
hello()
结果:
begin call [hello]
hello
end call [hello]
[>>>world]begin call [hello]
hello
[>>>world]end call [hello]
>>>
4:偏函数
- 当函数的参数个数太多,需要简化时,使用
functools.partial
可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。
----------------------------------------------------------------------------------------------------------------------------
参考网站:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
----------------------------------------------------------------------------------------------------------------------------