【问题标题】:Python decorator: TypeError: function takes 1 positional argument but 2 were givenPython 装饰器:TypeError:函数接受 1 个位置参数,但给出了 2 个
【发布时间】:2017-07-23 05:59:54
【问题描述】:

我正在尝试在 Python 中测试装饰器的实用性。当我写以下代码时,出现错误:

TypeError: fizz_buzz_or_number() takes 1 positional argument but 2 were given

我先定义一个函数log_calls(fn)

def log_calls(fn):
    ''' Wraps fn in a function named "inner" that writes
    the arguments and return value to logfile.log '''
    def inner(*args, **kwargs):
        # Call the function with the received arguments and
        # keyword arguments, storing the return value
        out = fn(args, kwargs)

        # Write a line with the function name, its
        # arguments, and its return value to the log file
        with open('logfile.log', 'a') as logfile:
            logfile.write(
               '%s called with args %s and kwargs %s, returning %s\n' %
                (fn.__name__,  args, kwargs, out))

        # Return the return value
        return out
    return inner

之后,我使用 log_calls 将另一个函数装饰为:

@log_calls
def fizz_buzz_or_number(i):
    ''' Return "fizz" if i is divisible by 3, "buzz" if by
        5, and "fizzbuzz" if both; otherwise, return i. '''
    if i % 15 == 0:
        return 'fizzbuzz'
    elif i % 3 == 0:
        return 'fizz'
    elif i % 5 == 0:
        return 'buzz'
    else:
        return i

当我运行以下代码时

for i in range(1, 31):
    print(fizz_buzz_or_number(i))

错误TypeError: fizz_buzz_or_number() takes 1 positional argument but 2 were given 来了。

我不知道这个装饰器有什么问题,以及如何解决这个问题。

【问题讨论】:

    标签: python python-3.x decorator python-decorators


    【解决方案1】:

    您在此处将 2 个参数传递给您的装饰函数:

    out = fn(args, kwargs)
    

    如果您想将args 元组和kwargs 字典用作变量参数,请回显函数签名语法,因此请再次使用***

    out = fn(*args, **kwargs)
    

    Call expressions reference documentation

    如果语法*expression 出现在函数调用中,则表达式的计算结果必须是可迭代的。这些迭代中的元素被视为附加的位置参数。

    [...]

    如果函数调用中出现语法**expression,则表达式必须计算为一个映射,其内容被视为附加关键字参数。

    【讨论】:

    • 我明白你的意思。我按照你的建议再试了一次,现在可以了。非常感谢。
    猜你喜欢
    • 2016-11-25
    • 2020-12-16
    • 2021-10-11
    • 1970-01-01
    • 2017-01-12
    • 2017-04-22
    • 2019-07-07
    • 2020-12-29
    • 2021-09-13
    相关资源
    最近更新 更多