【问题标题】:TypeError: fun() takes at least 2 arguments (3 given)TypeError: fun() 至少需要 2 个参数(给定 3 个)
【发布时间】:2017-06-04 05:07:26
【问题描述】:

这是我的代码:

def fun(x, y, b=None, c=None): 
    print(x,' ',y,' ',b,' ',c)

我将其称为fun(1, b=2, c=4) 并收到错误TypeError: fun() takes at least 2 arguments (3 given)。 我知道这个错误是因为位置和关键字参数的数量不正确。

而不是这个,每当我用不正确的号码调用我的函数时,我都想要。论点,它应该告诉我提供了哪个论点。 例如:对于上述情况,它应该说“没有提供参数 y”。

我可以为此编写一个装饰器吗?

【问题讨论】:

  • 请发布您的代码,否则我们无能为力。
  • 不清楚你想要发生什么。请澄清“我想处理这个错误并提示错误,就像它需要这些(名称)位置参数一样。”

标签: python typeerror python-decorators


【解决方案1】:

fun 定义的参数需要在 2 到 4 个之间,因为它有两个强制参数和两个可选参数。您没有提供以下两个强制性之一:

fun(1, b=2, c=4) # What about the argument y?

您需要使用以下形式之一调用它:

fun(1, 2)
fun(1, 2, b=3)
fun(1, 2, c=4)
fun(1, 2, b=3, c=4)

如果您想收到关于参数不足的通知,您可以使用argskwargs

def fun(*args, **kwargs):

    if len(args) < 2:
        print("Need at least two arguments!"); return
    if len(args) > 2 or len(kwargs) > 2:
        print("Too much arguments supplied!"); return

    x, y = args
    a, b = kwargs.get('a', None), kwargs.get('b', None)

    print(x, y, a, b)

【讨论】:

    【解决方案2】:

    我想处理这个错误并提示错误,就像它需要这些(名称)位置参数一样。是否可以为此编写一个装饰器?

    我做了一些研究,发现了inspect 模块。也许这些方面的东西就足够了?现在我正在捕获 TypeError 并打印一条消息,但您可能更喜欢抛出一个包含该消息的新 TypeError

    import inspect
    from functools import wraps
    
    
    def inspect_signature(f):
        signature = inspect.signature(f)
    
        @wraps(f)
        def decorator(*args, **kwargs):
            try:
                f(*args, **kwargs)
            except TypeError:
                print('Failed to call "{}" with signature {}. Provided args={} and kwargs={}.'.format(
                    f.__name__, signature, args, kwargs))
    
        return decorator
    
    
    @inspect_signature
    def func(foo, bar):
        print('Called successfully with foo={}, bar={}'.format(foo, bar))
        pass
    
    
    if __name__ == '__main__':
        func(foo='a', bar='b')
        func(foo='a')
        func('a', 'b', 'c')
    

    输出

    Called successfully with foo=a, bar=b
    Failed to call "func" with signature (foo, bar). Provided args=() and kwargs={'foo': 'a'}.
    Failed to call "func" with signature (foo, bar). Provided args=('a', 'b', 'c') and kwargs={}.
    

    【讨论】:

    • 我使用的是 python 2.7。它不支持inspect.signature()
    • @python_user (1) 请不要使用 Python 2。让它死吧。 (2)inspect.getargspec呢?我先尝试过,但它说它已被弃用。
    • 还有一点,我怎样才能保留函数签名?
    • @python_user 什么意思?
    • 在函数调用后尝试打印inspect.getargspec(func)。你会得到空的 argspec 像这样ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None).
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    相关资源
    最近更新 更多