python常用模块简介

python常用模块简介functools模块update_wrapper #修改装饰函数的属性原码如下:WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__', '__annotations__')WRAPPER_UPDATES = ('__di...
摘要由CSDN通过智能技术生成

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 wrapper 
    
  • 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 value
    
  • 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))
    

    module0002

  • 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 wrapper

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)
    
    module0001
  • 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 _gdy_paramCheck
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值