小白 study Py module

Pymodulestudy

1.inspect模块

函数注解中需要做位置参数的判断,无法和字典对应时,使用inspect模块,其提供获取对象的信息的函数,可以检查函数和类、类型检查

  • (1)signature(callable),获取签名(函数签名包含了函数名参数类型所在的类名称空间其他信息判断函数需要传入几个参数可以使用inspect.signature
import inspect
def add(x: int, y: int, *args, **kwargs) ->int:
    return x - y
sig = inspect.signature(add)
print(sig, type(sig))
print(0, sig.parameters)
print(1, sig.return_annotation)
print(2, sig.parameters['y'].annotation)
print(3, sig.parameters['args'])
print(4, sig.parameters['args'].annotation)
print(5, sig.parameters['kwargs'])
print(6, sig.parameters['kwargs'].annotation)
(x:int, y:int, *args, **kwargs) -> int <class 'inspect.Signature'>
output:
0 OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">), ('args', <Parameter "*args">), ('kwargs', <Parameter "**kwargs">)])
1 <class 'int'>
2 <class 'int'>
3 *args
4 <class 'inspect._empty'>
5 **kwargs
6 <class 'inspect._empty'>
  • (2)方法
inspect.isfunction(add)             
inspect.ismethod(add)                # 是否是类的方法
inspect.isgenerator(add)             # 是否是生成器对象
inspect.isgeneratorfunction(add)     # 是否生成器函数
inspect.isbuiltin(print)             # 是否内建对象
inspect.ismodule(print) 
inspect.isclass(print)
  • (3)Parameter对象

parameter保存在元组中,只读,name:参数名;annotation:参数注解,可能没定义;default:参数缺省值,可能没定义;empty:特殊的类,用来标记default属性或注释annotation属性的空值;kind:实参如何绑定到形参,就是形参大的类型

POSITONAL_ONLY    值必须是位置参数提供
VAR_POSITIONAL    值作为关键字或位置参数提供
VAR_POSIOTN       可变位置参数,*args
KEYWORD_ONLY      keyword-only参数
VAR_KEYWORD       可变关键字参数,**kwargs
def check(fn):
    def wrapper(*args, **kwargs):
        sig = inspect.signature(fn)
        params = sig.parameters      #有序字典 {变量名:参数对象}
        values = tuple(params.values())
#         print(0, values)
        for i, j in enumerate(args): #(4, 5) 要检查的参数子在args里面,要迭代它
            if isinstance(j, values[i].annotation):
#                 print(values[i].annotation)
                print('=-=-=-=-=')
            else:
                print('=!=!=!=!=')
        for k, v in kwargs.items():
            print(k, v)
            if isinstance(v, params[k].annotation): #params[k]有序字典用key获取value
                print(params[k].annotation)
                print('=-=-=-=-=')
            else:
                print('=!=!=!=!=')
        return fn(*args, **kwargs)
    return wrapper
@check     #add = check(add)
def add(x:int, y: int=7) ->int:
    return x, y
# add(4, 5)
# add(4, y=5)
# add(x=4, y=5)
add(4, 'a')
=-=-=-=-=
=!=!=!=!=
Out[73]:
(4, 'a')
-------------------------------------------------------------------
# 检查输入的参数类型是否为要求类型
def check(fn):
    def wrapper(*args, **kwargs):
        sig = inspect.signature(fn)
        params = sig.parameters      #有序字典 {变量名:参数对象}
        values = tuple(params.values())
        print(0, values)
        for i, j in enumerate(args): #(4, 5) 要检查的参数子在args里面,要迭代它
            print(i, j)
            if values[i].annotation != inspect._empty and not isinstance(j, values[i].annotation):
#                 print(values[i].annotation)
                print(j, '=!=!=!=!=')
        for k, v in kwargs.items():  
#             print(k, v)    # y:'5'
            if params[k].annotation != params[k].empty and not isinstance(v, params[k].annotation):
#                 print(params[k].annotation) inspect._empty == params[k].empty == inspect.Paramter.empty
                print(v, '=!=!=!=!=')
        return fn(*args, **kwargs)
    return wrapper
@check     #add = check(add)
def add(x, y: int=7) ->int:
    return x, y
# add(4, 5)
# add(4, y=5)
# add(x=4, y=5)
add('a', y='5')
0 (<Parameter "x">, <Parameter "y:int=7">)
0 a
5 =!=!=!=!=
Out[67]:
('a', '5')

2.functools模块

  • reduce

reduce 数据减少,可迭代对象不能为空,初始值没提供就在可迭代对象中区一个元素

reduce(function, sequence[, initial]) -> value
import functools
def fn(x):
    print(x)
    print(y)
    print('-' * 10)
    return x + y
functools.reduce(fn, range(1, 4))
1 2
----------
3 3
----------
6
functools.reduce(lambda x, y: x + y, range(5, 10), 100)
135
functools.reduce(lambda x, y: x * y, range(1, 6))             # 阶乘
120
  • partial

partial 偏函数,把函数部分的参数固定下来,为部分的参数添加了一个固定的默认值,形成一个新的函数并返回;行partial生成的新函数,是对原函数的封装

f = functools.partial(func, *args, **keywords)
import functools
import inspect
def add(x, y):
    return x + y
add1 = functools.partial(add, 4)
add1(5)
9
id(add), id(add1)
(2212138548760, 2212138584728)
inspect.signature(add1)
<Signature (y)>
add2 = functools.partial(add, x=5)
inspect.signature(add2)
<Signature (*, x=5, y)>
add2(x=2, y=3)
add3 = functools.partial(add, 4, 5)
functools.partial(<function add at 0x000002030DBB7E18>, 4, 5)
inspect.signature(add3)
<Signature ()>
add3()
9
add3(1)       #报错

def add(x, y, *args):
    print(x, y)
    print(args)
    return x + y
add4 = functools.partial(add, 1, 2, 3, 4)
add('a', 'b')
a b
()
Out[44]:
'ab'
inspect.signature(add4)
<Signature (*args)>
                  
#原理
import functools
import inspect
def add(x, y):
    print(x, y)
    return x + y
add1 = functools.partial(add, 1, y=5)
def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)  # {'x':5, 'y':5} 
        return func(*args, *fargs, **newkeywords) # add(1, 4, x=5, y=5)
    newfunc.func = func
    newfunc.keywords = keywords
    return newfunc
add1.func, add1.args, add1.keywords
(<function __main__.add(x, y)>, (1,), {'y': 5})
add1()
1 5
6                  
add1(4,x=5)       #报错
  • 缓存,@functools.lru.cathe(maxsize=128,type=False),maxsize为None时,禁用LRU,缓存可无限增长;maxsize是二的幂时,LRU功能执行的最好;type设置为True时,不同类型的函数参数将单独缓存
import time
import functools
@functools.lru_cache()
def add(x, y):
    time.sleep(2)
    return x + y
key1 = functools._make_key((), {'x':1, 'y':2}, False)
t1 = tuple(key1)
print(t1)
print(hash(t1))
print(key1.hashvalue)
functools.partial
#使用前提:(1)同样的函数参数一定得到同样的结果(2)函数执行过长,执行多次
本质:函数调用的参数==>返回值
缺点:不支持缓存过期,key无法过期、失效;不支持清除操作;不支持分布式,是一个单机的缓存
适用:需要时间换空间的时候

转载于:https://my.oschina.net/u/3844908/blog/3003758

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值