Multiple dispatch – "function requires at least 1 positional argument"

huangapple go评论72阅读模式
英文:

Multiple dispatch - "function requires at least 1 positional argument"

问题

在多重分派情况下,我不理解为什么会经常遇到错误消息:TypeError: some_func需要至少1个位置参数

例如,我们有以下函数:

from functools import singledispatch

@singledispatch
def some_func(a, b):
    ...
    
@some_func.register
def _(a: str, b: int):
    print(f'{a=}, {b=}')
    
@some_func.register
def _(a: str, b: bool):
    print(f'{b=}, {a=}')

如果我尝试运行:

some_func(a='a', b=10)

我会得到以下错误消息:

    872 def wrapper(*args, **kw):
    873     if not args:
--> 874         raise TypeError(f'{funcname}需要至少1个位置参数')
    875                         
    877     return dispatch(args[0].__class__)(*args, **kw)

TypeError: some_func需要至少1个位置参数

但是如果我将第一个参数设为位置参数,它就能正常工作:

some_func('a', b=10)   # 输出: a='a', b=10

接下来,我尝试将它们设置为仅关键字参数:

@singledispatch
def some_func(*, a, b):
    ...
    
@some_func.register
def _(*, a: str, b: int):
    print(f'{a=}, {b=}')
    
@some_func.register
def _(*, a: str, b: bool):
    print(f'{b=}, {a=}')

现在,如果我尝试使用关键字参数运行,我会得到相同的结果,但是如果我尝试将第一个参数设为位置参数,我会得到一个更符合预期的错误:

some_func('a', b=10)

File C:\Python39\lib\functools.py:877, in singledispatch..wrapper(*args, **kw)
    873 if not args:
    874     raise TypeError(f'{funcname}需要至少1个位置参数')
    875                     
--> 877 return dispatch(args[0].__class__)(*args, **kw)

TypeError: _()需要0个位置参数但提供了1个位置参数和1个仅关键字参数)。

所以现在该函数同时要求位置参数和不接受位置参数。

我不理解为什么会发生这种情况?需要位置参数的原因是什么?

英文:

In a multiple dispatch situation I don't understand why I constantly run into an error saying: TypeError: some_func requires at least 1 positional argument.

For example, we have a following function:

from functools import singledispatch

@singledispatch
def some_func(a, b):
    ...
    
@some_func.register
def _(a: str, b: int):
    print(f'{a=}, {b=}')
    
@some_func.register
def _(a: str, b: bool):
    print(f'{b=}, {a=}')

If I try to run:

some_func(a='a', b=10)

I get the error message:

    872 def wrapper(*args, **kw):
    873     if not args:
--> 874         raise TypeError(f'{funcname} requires at least '
    875                         '1 positional argument')
    877     return dispatch(args[0].__class__)(*args, **kw)

TypeError: some_func requires at least 1 positional argument

But it works fine if I make the first argument positional:

some_func('a', b=10)   # Out: a='a', b=10

Ok, then I'll try making them keyword-only...

@singledispatch
def some_func(*, a, b):
    ...
    
@some_func.register
def _(*, a: str, b: int):
    print(f'{a=}, {b=}')
    
@some_func.register
def _(*, a: str, b: bool):
    print(f'{b=}, {a=}')

Now if I try to run with keyword arguments I get the same result, but with this change if I try to make the first argument as positional I get a more expected error:

----> 1 some_func('a', b=10)

File C:\Python39\lib\functools.py:877, in singledispatch..wrapper(*args, **kw)
    873 if not args:
    874     raise TypeError(f'{funcname} requires at least '
    875                     '1 positional argument')
--> 877 return dispatch(args[0].__class__)(*args, **kw)

TypeError: _() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given

So now the function simultaneously: requires a positional-only argument and takes no positional arguments.

I don't understand why this is happening? What is the reason for needing a positional-only arguments?

答案1

得分: 1

这似乎是一个Python开放bug - 底层包装器期望至少有一个位置参数,否则会自动引发错误(请参阅包装器的定义)。

英文:

This seems to be an open python bug - the underlying wrapper expects at least one positional argument, otherwise an error is automatically raised (see definition of wrapper).

huangapple
  • 本文由 发表于 2023年5月15日 13:17:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76251041.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定