python常用模块简介
  z3GVikGFIRp0 2023年11月02日 45 0


python常用模块简介

functools模块

  • update_wrapper #修改装饰函数的属性
  • 原码如下:
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
'__annotations__')
WRAPPER_UPDATES = ('__dict__',)
def update_wrapper(wrapper,
wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
for attr in assigned:
try:
value = getattr(wrapped, attr)
except AttributeError:
pass
else:
setattr(wrapper, attr, value)
for attr in updated:
getattr(wrapper, attr).update(getattr(wrapped, attr, {})) #用wrapped的字典__dict__更新wrapper的字典__dict__

wrapper.__wrapped__ = wrapped #新增一个属性,记录原函数
return
  • wraps 结合update_wrapper修改装饰函数的属性
    *原码如下:
def wraps(wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
return partial(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
  • reduce(function,sequence[,initial])->value #缩减计算
  • function 函数,
  • sequence 可迭代对象,需要做递减计算的可迭代对象
  • initial 初始值,如果没有,默认从sequence中取出第一个值做初始值。
  • 相关原码:
def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
value = next(it)
else:
value = initializer
for element in it:
value = function(value, element)
return
  • partial->function #偏函数,吧函数部分参数固定下来,相当于为部分的参数添加了一个固定的默认值,形成一个新的函数并返回。
  • partial生成的新函数是对原函数的封装。
  • 伪代码示例
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy() #
newkeywords.update(fkeywords) #更新关键字参数
return func(*args, *fargs, **newkeywords) #注意,调用原函数时,先放的是位置参数,然后放的是再次传入的位置参数,最后放的是更新后的关键字参数
newfunc.func = func #新增一个属性,记录原函数
newfunc.args = args #新增一个属性,记录位置参数
newfunc.keywords = keywords #新增一个属性记录关键字参数
return newfunc #返回内建函数。
  • partial例子代码:
import functools,inspect
def add(x,y)->int:
return x+y
newadd = functools.partial(add,y=3)
print(newadd(5))
print(newadd(5,y=9))
print(newadd(y=8,x=7))
print(inspect.signature(newadd))
  • lru_cache(maxsize=128,typed=False) #是个装饰器,为函数生成缓存机制
  • Least-recently-used装饰器,lru最近最少使用。cache缓存
  • 如果maxsize设置为None,则禁用LRU功能,并且缓存可以无限制增长。当maxsize是二的次幂时,LRU功能执行得最好
  • 如果typed设置为True,则不同类型的函数参数将单独缓存。例如:f(3)和f(3.0)将被视为具有不同结果的不同调用。其原理是内部记录的每个参数的类型,计算根据参数字符串+参数类型计算hash值。
  • lru_cache装饰器使用前提
  • 同样的函数参数一定得到相同的结果
  • 函数执行时长很长,且要多次执行
  • lru_cache本质上是用一个字典记录了函数调用参数组成的字符串做key,和计算的值做value,如果下次调用发现参数一直,就直接从字典中取出对应的值返回。避免重复计算
  • 缺点:
  • 不支持缓存过期,key无法过期、失效
  • 不支持清除操作
  • 不支持分布式,是一个单机的缓存
  • 使用场景,单机上需要空间换时间的地方,可以用缓存来将计算变成快速查询
  • 简单示例:用公式求斐波拉系数列。使用缓存
import functools
@functools.lru_cache(maxsize=50)
def getnum(n):
return 1 if n<3 else getnum(n-1)+getnum(n-2)
functools模块经典应用
  • 函数运行时长统计
def gdy_time(fn):
"""
时间统计,统计函数执行时间
:param fn: 需要装饰的函数
:return: 包装后的fn
"""
@functools.wraps(fn)
def wrapper(*args,**kwargs):
start = datetime.datetime.now()
req = fn(*args,**kwargs)
timeout = datetime.datetime.now() - start
gdy_print("{}方法耗时:{},args={},kwargs={},\n执行结果:req={}".format(fn.__name__,timeout.total_seconds(),args,kwargs,req))
return req
return

inspect模块

  • signature(callable)-><class ‘inspect.Signature’> 获取签名(函数签名包含了一个函数的信息,包括函数名,它的产生类型、它所在的类和名称空间及其他信息)
  • 签名返回类型为inspect.Signature类型
  • parameters属性,记录了函数中定义是注解和参数。parameters实际上是一个字典。
  • annotation 可以获取parameters对应value值的类型,即定义是注解说明的类型。
  • 简单示例
import inspect

def add(x,y:int=5,*args,k,z=4,**kwargs):
return x+y
sig = inspect.signature(add) #获取函数签名
print(sig,type(sig)) #函数签名
print("params =",sig.parameters) #记录参数
print(sig.parameters['y'],type(sig.parameters['y']))
print(sig.parameters['y'].annotation) #y参数的类型
print(sig.parameters['x'])
print(sig.parameters['x'].annotation) #如果定义函数参数时没添加注解类型,默认为inspect._empty空类型
print(sig.parameters['args'])
print(sig.parameters['args'].annotation)
print(sig.parameters['kwargs'])
print(sig.parameters['kwargs'].annotation)
  • isfunction(name)-> True|False #是否是函数
  • ismethod(name)-> True|False #是否是类方法
  • isgenerator(name)-> True|False #是否是生成器对象
  • isgeneratorfunction(name)-> True|False #是否是生成器函数
  • isclass(name)-> True|False #是否是类
  • ismodule(name)-> True|False #是否是模块
  • isbuiltin(name)-> True|False #是否是内建对象
  • Parameter 对象,是一个类
  • 类的属性有name,annotation,default,empty,kind保存在元组中是可读的
  • name:参数名字
  • annotation:参数注解。(有时候可能没有定义)
  • default:参数缺省值,(有时候可能没有定义)
  • empty:特殊类,用来标记default属性或者注释annotation属性的空值
  • kind:实参如何绑定到形参,就是形参的类型
  • POSITIONAL_ONLY,值必须是位置参数提供
  • POSITIONAL_OR_KEYWORD,值可以作为关键字或者位置参数提供
  • VAR_POSITIONAL,可变位置参数,对应*args
  • KEYWORD_ONLY,keyword-only参数,对应* 或者 *args之后出现的费可变关键字参数
  • VAR_KEYWORD,可变关键字参数,对应**kwargs
inspect模块经典应用
  • 参数检查
def gdy_paramCheck(fn):
"""
参数检查
:param fn: 需要检查的函数
:return: 包装后的fn
"""
@functools.wraps(fn)
def _gdy_paramCheck(*args,**kwargs):
params = inspect.signature(fn).parameters #对函数签名,获取参数注解字典
for ag,(k,v) in zip(args,params.items()): ##检查位置参数
v:inspect.Parameter = v #利用参数注解,告诉编译器v是Parameter类型。本行可以删除,只是帮助编译器给出提示
# print(k=="args")
if k == "args": break #如果碰到args收集多个位置参数,就直接跳出循环。
if v.annotation != inspect._empty and not isinstance(ag,v.annotation):
# raise TypeError(""{}={},参数类型错误!错误类型:{},类型应为:{}".format(k,ag,type(ag),v.annotation))
print("{}={},参数类型错误!错误类型:{},类型应为:{}".format(k,ag,type(ag),v.annotation))
return
for k,v in kwargs.items():
key:inspect.Parameter = params[k] #利用参数注解,告诉编译器key是Parameter类型。本行可以删除,只是帮助编辑器能给出提示
if key.empty != key.annotation and not isinstance(v,key.annotation):
# raise TypeError("{}={},参数错误!错误类型:{}类型应为:{}".format(k,v, type(v),key.annotation))
print("{}={},参数错误!错误类型:{}类型应为:{}".format(k,v, type(v),key.annotation))
return
return fn(*args,**kwargs)
return


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
z3GVikGFIRp0
作者其他文章 更多