【问题标题】:decorator enquiry in pythonpython中的装饰器查询
【发布时间】:2019-03-02 11:55:35
【问题描述】:

我是一名自学成才的程序员,在 python 中的 @decorator 方面需要您的帮助。

这是我的问题。在我用装饰器运行 other(multiply) 之后,它出现了一个错误: wrap_func() 接受 0 个位置参数,但给出了 1 个。我不知道为什么以及如何解决这个问题。 我的主要目的是学习装饰器是如何工作的;因此下面的代码可能没有意义。

def multiply(a,b):
    return a*b
###pass in multiply function in other()

def other(multiply):
    print('passed in')
    print(multiply(1,2))

other(multiply)
### result shows passed in and 2, as expected

### Set up decorator func here
def decorator_prac(old_func):

    def wrap_func():
        multiply(1,2)
        old_func()
        print(1+7)
    return wrap_func

###add decorator on def other(multiply)
@decorator_prac
def other(multiply):
    print('what should I say')
    print(multiply(1,2))

###Run other(multiply)
other(multiply)

输出:

passed in
2
Traceback (most recent call last):
  File "so.py", line 28, in <module>
    other(multiply)
TypeError: wrap_func() takes 0 positional arguments but 1 was given

【问题讨论】:

  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。您发布的内容因各种缩进错误而死,也许还有其他问题。
  • 我想我修正了缩进...我更新了你的帖子,现在我的输出与你的解释和 cmets 兼容。请验证。
  • @Prune,谢谢....没有意识到缩进。我的坏
  • @Prune,但我该如何解决这个错误?

标签: python python-decorators


【解决方案1】:

您传递的函数和使用它的方式之间存在差异。这是跟踪和解决方案。我仔细检查了装饰器看到的函数,然后添加了所需的参数。如果您需要它是通用的,则需要一个通用参数列表,例如 *args

### Set up decorator func here
def decorator_prac(old_func):
#def decorator_prac(old_func):
    print("decorator arg", old_func)    # Track what is passed in

    def wrap_func(func_arg):            # Accommodate the function profile
        multiply(1,2)
        old_func(func_arg)              # Implement the proper profile
        print(1+7)
    return wrap_func

输出:

passed in
2
decorator arg <function other at 0x7f0e7b21b378>
what should I say
2
8

【讨论】:

  • 但是根据我的理解,当我把multiply函数作为old_func时,old_func(func_arg)的函数变成了multiply(func_org),我不明白multiply(func_org)怎么能工作?跨度>
  • 你理解错了:func_argmultiply,这样old_func(func_arg) 就变成了other(multiply)。然后你打电话给multiply(1, 2),你会看到结果。我建议您插入更多 print 命令,类似于我提供的命令,以通过您的代码跟踪数据流。
【解决方案2】:

装饰器接受一个函数对象(此处为:other(multiply))并返回另一个函数wrap_func() 替换它。 other 这个名字现在指的是被替换的函数。

虽然原始函数有参数,但替换函数没有。以所示方式调用带参数的无参数函数失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2018-11-23
    • 2016-08-21
    • 2013-08-07
    • 2014-01-23
    • 2020-02-10
    相关资源
    最近更新 更多