标签:学记笔记
高阶函数函数可以作为普通变量、参数、返回值等等
指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数
z = f(x, y) ==> z = f(x)(y)
def add(x, y):
return x + y
转换如下
def add(x):
def _add(y):
return x+y
return _add
add(5)(6)
通过嵌套函数就可以把函数转换成柯里化函数
在OOP设计模式中,装饰器属于一种装饰模式
装饰器语法是一个语法糖
def logger(func):
def wrapper(*args, **kwargs):
print(‘call ‘ + func.__name__)
return func(*args, **kwargs)
return wrapper
@logger # 等价于add = logger(add)
def add(x,y):
return x + y
装饰器是高阶函数,但装饰器是对传入函数的功能的装饰(功能增强)
解决方法:
def copy_properties(src, dst): # 可以改造成装饰器
dst.__name__ = src.__name__
dst.__doc__ = src.__doc__
import datetime, time, functools
def logger(duration, func=lambda name, duration: print(‘{} took {}s‘.format(name, duration))):
def _logger(fn):
def wrapper(*args,**kwargs):
start = datetime.datetime.now()
ret = fn(*args,**kwargs)
delta = (datetime.datetime.now() - start).total_seconds()
if delta > duration:
func(fn.__name__, duration)
return ret
return functools.update_wrapper(wrapper, fn)
return _logger
@logger(5) # add = logger(5)(add)
def add(x,y):
time.sleep(1)
return x + y
print(add(5, 6), add.__name__, add.__wrapped__, add.__dict__, sep=‘\n‘)
import datetime, time, functools
def logger(duration, func=lambda name, duration: print(‘{} took {}s‘.format(name, duration))):
def _logger(fn):
@functools.wraps(fn)
def wrapper(*args,**kwargs):
start = datetime.datetime.now()
ret = fn(*args,**kwargs)
delta = (datetime.datetime.now() - start).total_seconds()
if delta > duration:
func(fn.__name__, duration)
return ret
return wrapper
return _logger
@logger(5) # add = logger(5)(add)
def add(x,y):
time.sleep(1)
return x + y
print(add(5, 6), add.__name__, add.__wrapped__, add.__dict__, sep=‘\n‘)
将记录的功能提取出来,这样就可以通过外部提供的函数来灵活的控制输出
形如:
def add(x:int , y:int) -> int :
‘‘‘
:param x: int
:param y: int
:return: int
‘‘‘
return x + y
变量注解使用较少
signature(callable),返回一个Signature类对象。获取签名(函数签名包含了一个函数的信息,包括函数名、它的参数类型、它所在的类和名称空间及其他信息)
sig = signature(fn)
params = sig.parameters
Signature类对象的parameters方法返回的是一个orderedDict,其key值为fn的形参名,value值为Parameter类对象
保存在元组中,是只读的
思路
inspet模块提供获取对象信息的函数,可以检查函数和类、类型检查
import inspect
def check(fn):
def wrapper(*args,**kwargs):
sig = inspect.signature(fn)
params = sig.parameters #是orderedDict
values = list(params.values()) #可迭代对象转化成列表,处理后也是有序的
for k,v in enumerate(args): #因为values、args都有序
if values[k].annotation is not inspect._empty and not isinstance(v,values[k].annotation):
return ‘{}`s input is {} type , expected {}‘.format(v,type(v),values[k].annotation)
for k,v in kwargs.items(): #kwargs与params都为字典形式,键值相同
if params[k].annotation is not inspect._empty and not isinstance(v, params[k].annotation):
return ‘{}`s input is {} type , expected {}‘.format(k,type(v),params[k].annotation)
return fn(*args,**kwargs)
return wrapper
@check
def add(x:int,y:int):
return x + y
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords): # 包装函数
newkeywords = keywords.copy() #将原函数关键字参数拷贝后,
newkeywords.update(fkeywords) #将调用新函数时的关键字参数更新
return func(*(args + fargs), **newkeywords) #调用新函数时的参数是建立偏函数时给的参
#数,再各加上调用新函数时的参
newfunc.func = func # 保留原函数,注意:如果原函数已有装饰器,func属性内容有可能不是原函数名,而是装饰器函数名
newfunc.args = args # 保留原函数的位置参数
newfunc.keywords = keywords # 保留原函数的关键字参数参数
return newfunc
如果typed设置为True,则不同类型的函数参数将单独缓存。例如,f(3)和f(3.0)将被视为具有不同结果的不同调用
如果全为位置实参且位置与数值都相同,则视为相同实参,或者全传关键字参数则即使顺序不同也视为相同实参,即缓存能使用上;其他情况则皆视为不同实参
源码:
def _make_key(args, kwds, typed,
kwd_mark = (object(),),
fasttypes = {int, str, frozenset, type(None)},
tuple=tuple, type=type, len=len):
"""Make a cache key from optionally typed positional and keyword arguments
The key is constructed in a way that is flat as possible rather than
as a nested structure that would take more memory.
If there is only a single argument and its data type is known to cache
its hash value, then that argument is returned without a wrapper. This
saves space and improves lookup speed.
"""
key = args
if kwds:
key += kwd_mark
for item in kwds.items():
key += item
if typed:
key += tuple(type(v) for v in args)
if kwds:
key += tuple(type(v) for v in kwds.values())
elif len(key) == 1 and type(key[0]) in fasttypes:
return key[0]
return _HashedSeq(key)
标签:学记笔记
原文地址:http://blog.51cto.com/11281400/2106508