2017-03-03 43 views
0

我想在Python中测试装饰器的实用程序。当我写以下代码,有一个错误:Python装饰器:TypeError:函数需要1个位置参数,但有2个被给出

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

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

回答

0

您传递2个参数给你的装饰功能在这里:

out = fn(args, kwargs) 

如果你想申请的args元组和kwargs字典作为变量参数,回声函数签名语法,所以再次使用***

out = fn(*args, **kwargs) 

Call expressions reference documentation

If the syntax *expression appears in the function call, expression must evaluate to an iterable. Elements from these iterables are treated as if they were additional positional arguments.

[...]

If the syntax **expression appears in the function call, expression must evaluate to a mapping, the contents of which are treated as additional keyword arguments.

+0

我明白你的意思了。我根据你的建议再试一次,现在可以使用。非常感谢。 – Luhuimiaomiao

相关问题