Python decorator:TypeError:函数接受1个位置参数,但给出了2个

Python decorator:TypeError:函数接受1个位置参数,但给出了2个,python,python-3.x,decorator,python-decorators,Python,Python 3.x,Decorator,Python Decorators,我试图在Python中测试decorator的实用性。当我编写以下代码时,出现了一个错误: TypeError: fizz_buzz_or_number() takes 1 positional argument but 2 were given 我首先将函数log\u calls(fn)定义为 def log_calls(fn): ''' Wraps fn in a function named "inner" that writes the arguments and re

我试图在Python中测试decorator的实用性。当我编写以下代码时,出现了一个错误:

TypeError: fizz_buzz_or_number() takes 1 positional argument but 2 were given
我首先将函数
log\u 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_调用将另一个函数修饰为:

@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\u buzz\u或\u number()接受1个位置参数,但给出了2个


我不知道这个装饰器出了什么问题,也不知道如何修复它。

您在这里向装饰函数传递了两个参数:

out = fn(args, kwargs)
如果要将
args
元组和
kwargs
字典作为变量参数应用,请回显函数签名语法,因此再次使用
*
**

out = fn(*args, **kwargs)
见:

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

[……]

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


我明白你的意思。我根据你的建议再试了一次,现在可以了。谢谢。