高阶函数
- 数学概念 y=g(f(x))
- 在数学和计算机科学中,高阶函数应当至少满足下面一个条件的函数
条件1. 接受一个或多个函数作为参数
条件2. 输出一个函数
举例:
def counter(base):
def inc(step=1):
nonlocal base #修改外部变量base,赋值需要nonlocal
base += step
return base
return inc foo = counter(5)
foo1 = counter(5) print(foo == foo1) #False print(id(foo),foo)
print(id(foo1),foo1)
柯里化
- 指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数
- z = f(x,y) 转换成 z = f(x)(y)的形式
举例:
有这样一个add函数
def add(x,y): #柯里化成 add(x)(y) 的格式
return x + y
将此函数柯里化
def add(x):
def _add(y):
return x + y
return _add foo = add(7) #等同于 add(7)(8)
print(foo(8))
闭包
- 函数中用到了外层变量就形成了闭包,如果想对外层变量修改,可以使用 global 或者 nonlocal 声明。
*变量
- 对闭包来说外层变量就是*变量,不在本地作用域的变量。
生成器
- 惰性求值,使用yield关键字可以构造一个生成器函数,调用这个函数就得到一个生成器对象。
- 使用next函数多次执行。
- 简单理解就是需要的时候才求值。
- 下面的例子是模拟一个无限增长的user_id号:
def increasing():
id = 0
while True:
id += 1
yield id user_id = increasing() for _ in range(10):
print(next(user_id))
装饰器(无参)
- 装饰器本身是一个函数
- 需要一个函数作为它的形参
- 返回值也是一个函数
- 可以使用@functionname 方式,简化调用,语法糖
- 也是高阶函数,两个条件都满足,但装饰器是对传入函数的功能的装饰(功能增强)
举例:
def logger(fn):
def _logger(*args,**kwargs):
print('before')
ret = fn(*args,**kwargs)
print('after')
return ret
return _logger @logger # add = logger(add)
def add(x,y):
return x + y print(add(5,600))
带参装饰器:
- 装饰器返回的是内层函数的引用
举例:
import functools
import datetime
import time def copy_property(src):
def _copy_property(dst):
dst.__name__ = src.__name__
dst.__doc__ = src.__doc__
#dst.__qualname__ = src.__qualname__ #限定名
return dst
return _copy_property def timeoutTip(t):
def logger(func):
#@functools.wraps(func)
@copy_property(func)
def wrapper(*args, **kwargs):
'''test2'''
# before 功能增强
start = datetime.datetime.now()
# print('Call:{}() StartTime:{} nowDescription:{}'.format(func.__name__,start,func.__doc__),end='\t\t')
print('Call:{}()'.format(func.__name__), end='\t\t')
ret = func(*args,**kwargs)
# after 功能增强
stopTime = (datetime.datetime.now() - start).total_seconds() if stopTime > t:
print('Timeout time:{} '.format(stopTime))
return ret # copy_property(func, wrapper)
return wrapper
return logger @timeoutTip(2) #带参装饰器与不带参装饰器的区别
def add(x,y):
'''test1'''
#time.sleep(3)
print('returnValue = x+y')
return x+y print(add(100,y=200))
print(add.__doc__,add.__qualname__)