【问题标题】:Use decorators to call function without arguments使用装饰器调用不带参数的函数
【发布时间】:2019-03-09 08:30:45
【问题描述】:

为了使我的代码更清晰(主要是)我自己阅读,我尝试使用装饰器将大部分函数参数放入@decorator(args),然后调用不带参数的函数。这是我当前的代码:

def dec1(*args, **kwargs):
    def dec2(func):
        return func(*args, **kwargs)
    return dec2

@dec1(1, 2, 3)
def func1(val1, val2, val3):
    print(val1)
    print(val2)
    print(val3)

if __name__ == "__main__":
    func1()

但是,它正在报告这个(本质上是使用装饰器运行代码,而不是第二个函数调用):

1
2
3
Traceback (most recent call last):
  File "/home/shadowrylander/decorator_test.py", line 13, in <module>
    f1()
TypeError: 'NoneType' object is not callable

我正在尝试完成的操作类似于 Click 库所做的(使用参数定义 hello(),然后使用无参数调用它):

import click

@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s!' % name)

if __name__ == '__main__':
    hello()

如果有人能帮我创建一个类似的装饰器,我将不胜感激,如果之前已经有人问过和/或回答过这个问题,我深表歉意;我要么无法正确理解它们,要么找不到问题!
感谢您的帮助!

【问题讨论】:

  • 如果您只想使用硬编码值,为什么您的函数还要使用这些参数?
  • 在装饰器中将 func1 更改为 func。当您调用包装函数时,func1 指的是修饰函数,而不是原始定义。
  • 带参数的装饰器应该返回真正的装饰器。见这里stackoverflow.com/questions/5929107/decorators-with-parameters。另见 functools.partial
  • 另外,您发布的错误不是您发布的代码版本产生的错误。
  • @user2357112:仅用于说明目的;我想使用几乎任何带有装饰器的函数,它可以接受任何参数并传递它!

标签: python decorator python-decorators


【解决方案1】:

dec2 中,您返回的是使用指定参数调用func1 的结果,这不是您想要的。

你想要的是返回一个函数f,它使用指定的参数调用func1,即:

def dec1(*args, **kwargs):
    def dec2(func):
        def f():
            return func(*args, **kwargs)
        return f
    return dec2

 

更详细的解释:

记住装饰器语法:

@dec1(1, 2, 3)
def func1(val1, val2, val3):
    ...

在语法上等同于:

def func1(val1, val2, val3):
    ...
func1 = dec1(1, 2, 3)(func1)

所以dec1(...) (dec2) 的结果是在您装饰函数时使用装饰函数 (func1) 作为参数调用的。因此,您不希望 dec2 做任何事情,而是返回一个稍后在调用它时会做某事的函数。

【讨论】:

  • 就是这样!谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-03-22
  • 2014-07-21
  • 2017-10-17
  • 1970-01-01
  • 2014-02-21
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
相关资源
最近更新 更多