【问题标题】:python decorator - is it possible to return a function that expects more params?python decorator - 是否可以返回一个需要更多参数的函数?
【发布时间】:2021-03-31 10:15:05
【问题描述】:

我有一个非常简单的函数,定义为

def test(x):
   return x

我想用一个装饰器包装它,它返回一个需要另一个 kwargs 参数的函数。

@simple_dec
def test(x):
   return x

在该装饰器函数中,我会从 kwargs dict 中弹出该参数,并且只需调用 test 函数并使用测试期望得到的参数,而不会破坏它:

def simple_dec():

     def simple_dec_logic(func, *args, **kwargs):
          kwargs.pop("extra_param")
          return func(*args, **kwargs)

     return decorator.decorate(_func, simple_dec_logic)

我的问题是 - 包装后,如果我打电话:

test(1, extra_param=2)

它在“测试得到意外的参数 extra_param”时失败,尽管如果代码实际运行,装饰器会处理这个并调用测试函数,没有那个参数。如果我理解正确,解释器会在运行代码并知道它是用装饰器定义之前失败。

有没有办法解决这个问题?我想让装饰器让我用更多的参数调用测试函数,而不是在测试函数中定义它们。

【问题讨论】:

  • 为什么不用*kwargs 定义test
  • 我想将此装饰器添加到我拥有的现有功能中,并且我不想修改所有功能
  • 听起来你要传递的附加参数与装饰函数完全无关。您是否考虑过使用带有参数的装饰器? stackoverflow.com/questions/5929107/decorators-with-parameters
  • 我的装饰器实际上已经用参数定义了。但我想要的是能够动态覆盖其中的一些。例如:我有一个缓存装饰器,它用 ttl 参数包装一个函数。 @cache(ttl = 10) def test(x) 我想有一个选项来调用 test 像 text(x=1, clear_cache=True) 这样的东西。
  • 什么是decorator.decorate

标签: python python-decorators


【解决方案1】:

这很好用:

import functools

def decorator(func):
    @functools.wraps(func)
    def wrapper_decorator(*args, **kwargs):
        kwargs.pop('extra_param')
        value = func(*args, **kwargs)
        return value
    return wrapper_decorator

@decorator
def test(x):
    return x

test(1, extra_param=2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 2014-10-23
    • 2020-02-20
    • 2014-01-16
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    相关资源
    最近更新 更多