【问题标题】:How to wrap a third party decorator with my own in python如何在 python 中用我自己的包装第三方装饰器
【发布时间】:2022-01-07 12:59:10
【问题描述】:

我看到很多用你自己的装饰器包装的例子,但它们都是关于自定义装饰器的。我有一个可以使用的第三方装饰器,例如:

@someSDK
myFunction()

我想要做的是将它包装在我自己的装饰器中,仅当 env 设置为 true 时才调用 @someSDK

编辑: 具体来说,第 3 方装饰者是 @xray_recorder.capture() 。我想要我自己的装饰器,只有当我有一个变量设置为某个标志时才会实现这个。

这是我目前的一个粗略想法:

if CUSTOM_XRAY_WRAPPER is True:
    @xray_recorder.capture()
    def wrapper(*args, **kwargs):
        val = func(*args, **kwargs)
        return val
    return wrapper
else:
    def wrapper(*args, **kwargs):
        val = func(*args, **kwargs)
        return val
    return wrapper

【问题讨论】:

    标签: python python-3.x amazon-web-services decorator python-decorators


    【解决方案1】:

    作为一个小例子,因为您没有提供最小的可重现示例:

    CUSTOM_XRAY_WRAPPER = True
    
    def xray_capture(func):
        def wrapper(*args, **kwargs):
            print('recodring')
            return func(*args, **kwargs)
        return wrapper
    
    def yourdecorator(func):
        if CUSTOM_XRAY_WRAPPER:
            return xray_capture(func)
        return func
    
    @yourdecorator
    def yourfunction(text):
        print(text)
    

    在这里,在函数上使用 xray_capture 装饰器会在执行该函数之前打印“记录”。如果 CUSTOM_XRAY_WRAPPER 为 False,函数 yourdecorator 可以用作装饰器,而不是返回正常函数。如果为 True,则返回用xray_capture 修饰的函数。

    顺便说一句,您不必写 CUSTOM_XRAY_WRAPPER == True,因为它已经是 True 或 False,这意味着您正在检查是 True == True 还是 False == True

    转移到你的例子,这看起来像这样:

    def yourdecorator(func):
        if CUSTOM_XRAY_WRAPPER:
            xray_recorder.capture()(func)
        return func
    

    【讨论】:

    • 我在包装器之前添加注释的方式不正确吗?
    • 嗯,你的版本肯定是不正确的。据我所知,您从未真正定义过真正的装饰器。你只定义一个包装函数。
    【解决方案2】:

    你需要记住的是

    @decorator
    def foobar():
         ...
    

    等价于

    def foobar():
       ...
    foobar = decorator(foobar)
    

    所以你想要的是

    def my_decorator(f):
        if CUSTOM_XRAY_WRAPPER:
           return xray_recorder.capture()(f)
        else:
           return f
    

    【讨论】:

      【解决方案3】:

      您可以重命名装饰器并使用传递:

      from functools import wraps
      
      
      MY_ENV_VAR = True
      
      
      # create a pass-through wrapper
      def sample_decorator(f):
          @wraps(f)
          def wrapper(*args, **kwargs):
              return f(*args, **kwargs)
          return wrapper
      
      
      # now you can just use the same decorator everywhere
      if MY_ENV_VAR:
          # use your recorder.capture 
          x_ray_capture = xray_recorder.capture()
      else:
          # pass-through
          x_ray_capture = sample_decorator
      
      
      @x_ray_capture
      def foo():
          # do something
      

      【讨论】:

      • 第一个if不应该是xray_recorder.capture()吗?
      • @qaispak 应该,已修复
      猜你喜欢
      • 2020-11-13
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多