python_如何定义带参数的装饰器?

案例:

实现一个装饰器,用它来检查被装饰函数的参数类型。

需求:

    装饰器可以通过函数,指明函数参数类型,进行函数调用的时候,传入参数,检测到不匹配时,抛出异常

如何解决这个问题?

  1. 先要获取函数的签名,并且获得装饰器中参数,然后把函数签名和装饰器中参数对应绑定
  2. 把调用函数时候传入的参数和函数签名进行绑定
  3. 把实参和装饰器中定义的数据进行类型比较,不匹配抛出异常

    #!/usr/bin/python3
    
    from inspect import signature
    
    def check_type(*ty_args, **ty_kwargs):
    
        def out_wrapper(func):
            # 通过signature方法,获取函数形参:name, age, height
            sig = signature(func)
            # 获得装饰器传来的参数, 函数签名与之绑定,字典类型
            bind_types = sig.bind_partial(*ty_args, **ty_kwargs).arguments
            print(bind_types)
    
            def wrapper(*args, **kwargs):
                # 给执行函数中具体的实参进行和形参进行绑定,形成字典的形式
                func_type = sig.bind(*args, **kwargs).arguments.items()
                print(func_type)
                # 循环形参和实参字典的items()形式
                for name, obj in func_type:
                    if name in bind_types:
                        if not isinstance(obj, bind_types[name]):
                            raise TypeError(‘%s must be %s‘ % (name, bind_types[name]))
                func(*args, **kwargs)
            return wrapper
        return out_wrapper
    
    # 通过装饰器实现对函数参数进行类型检查
    @check_type(str, int, float)
    def func(name, age, height):
        print(name, age, height)
    
    if __name__ == ‘__main__‘:
        func(‘bei_men‘, 18, 1.75)
    

      

时间: 2024-12-12 22:58:35

python_如何定义带参数的装饰器?的相关文章

Python带参数的装饰器

在装饰器函数里传入参数 # -*- coding: utf-8 -*- # 2017/12/2 21:38 # 这不是什么黑魔法,你只需要让包装器传递参数: def a_decorator_passing_arguments(function_to_decorate): def a_wrapper_accepting_arguments(arg1, arg2): print("I got args! Look:", arg1, arg2) function_to_decorate(ar

Python中带参数的装饰器

装饰器本身是用来是为一个函数是实现新的功能,并且不改变原函数的代码以及调用方式. 遇到这样一种问题: 众多函数调用了你写的装饰器,但客户有需求说,我想实现我可以随之控制装饰器是否生效. 那你就不可能在得到命令的时候去原函数头部去做删除和添加装饰器调用的命令.这是就可以用到带参数的装饰器,定义一个开关,调用装饰器的时候,把这个装饰器的开关参数给传递进去,这样当开关打开的时候装饰器生效,关闭的时候则只执行原函数的代码. 举例:开关参数为True的时候执行过程: 1 F = True #step 1

python装饰器详解,多层装饰器,及带参数的装饰器。

pyhon学习有一段时间了,今天又碰到了Django的中间件,其实Django里面的中间件,就是用了多层的装饰器,然后去了解了一下多层装饰器,感觉有写东西差不多快忘了,也可能前面没学好. 现在重新记录,学习下. 普通装饰器: def warp(func): print('我是装饰器,碰到需要装饰的函数,一开始执行这里') def inner(*args, **kwargs): print('这里才是真正的装饰开始!') res = func(*args, **kwargs) print('装饰结

22_装饰器、带参数的装饰器、多个装饰器装饰一个函数

一.装饰器的执行流程 1 def wrapper(func): 2 def inner(*args,**kwargs): 3 ret = func(*args,**kwargs) 4 return ret 5 return inner 6 7 @wrapper #fun = wrapper(fun) 8 def fun(s): 9 print('666') 10 return s 11 12 fun('777') 13 print(fun('777')) 14 15 ''' 16 1.程序至上而

python 第十二天2018.04.01 带参数的装饰器,,函数的有用信息

一.带参数的装饰器,函数的有用信息 def func1(): '''此函数的功能是完成的登陆的功能 return: 返回值是登陆成功与否(true,false) ''' print(333) func1() print(func1.__name__)#func1 print(func1.__doc__)#此函数的功能是完成的登陆的功能,return: 返回值是登陆成功与否 打印函数名 from functools import wraps def wrapper(f): @wraps(f) de

带参数的装饰器,多个装饰器装饰一个函数,函数的有用信息。

带参数的装饰器.import time def timer_out(flag1): #falg1 = flag def timer(f): def inner(*args, **kwargs): if flag1: start_time = time.time() time.sleep(0.3) ret = f(*args, **kwargs) end_time = time.time() print('执行效率%s' % (end_time-start_time)) return ret el

Python全栈__函数的有用信息、带参数的装饰器、多个装饰器装饰一个函数

1.函数的有用信息 代码1: 1 def login(username, password): 2 """ 3 此函数需要用户名,密码两个参数,完成的是登录的功能. 4 :return: True 登录成功. False登录失败. 5 """ 6 print(login.__name__) 7 print(login.__doc__) 8 print('登录成功...') 9 return True 10 11 print(login.__nam

带参数的装饰器

#!/usr/bin/env python # -*- coding:utf-8 -*- # 作者: Apollo # 邮箱: [email protected] # 博客: http://www.zgerji.online/ import time flag = True def timmer_out(f): def timmer(func): def inner(*args, **kwargs): '''执行函数前操作''' if f: start_time = time.time() ti

python-day14--带参数的装饰器+多个装饰器装饰同一个函数

1.# 带参数的装饰器def f1(flag): def f2(func): def inner(*args,**kwargs): if flag: '''执行函数之前要做的''' r=func(*args,**kwargs) if flag: '''执行函数之后要做的''' return r return inner return f2@f1(True)def f3(): print('egon') return ('eva')s=f3()print(s) 2.#多个装饰器装饰一个函数 def