Python库函数不带关键字参数

时间:2019-05-03 12:43:37

标签: python functional-programming keyword-argument functools

当我尝试对python中的问题应用功能更强的方法时,就会出现此问题。 我试图做的就是简单地将一个数字列表平方起来,没什么大不了的。

from operator import pow
from functools import partial 

squared = list(map(partial(pow, b=2), range(10))

事实证明,这没有用。 TypeError: pow() takes no keyword arguments

很困惑,我检查了pow(b=2, a=3)是否这样做。没有。

我已经检查过operator source code,没有任何可疑之处。

困惑,我开始怀疑自己的python知识,我自己做了一个pow函数。

def pow(a, b):
  return a ** b

然后,我尝试对函数执行相同的操作,令人惊讶的是,一切正常。

我不会猜测问题的原因是什么,我要问的只是为什么这件事,以及是否存在解决方法。

4 个答案:

答案 0 :(得分:4)

如果使用交互式外壳程序中的help()功能检查内置pow()operator.pow()的签名,您将看到它们仅要求 position 参数(注意斜杠):

pow(x, y, z=None, /)
pow(a, b, /)

原因是这两个函数都是用C实现的,并且没有名称作为参数。您必须按位置提供参数。解决方法是,您可以创建一个纯Python pow()函数:

def pow(a, b):
    return a ** b

另请参阅常见问题解答中的What does the slash(/) in the parameter list of a function mean?

答案 1 :(得分:1)

在Python的当前版本中,许多CPython“内置”函数和标准库函数仅接受仅位置参数。通过调用help方法可以很容易地观察得到的语义。

  

>>>>help(pow)

     

有关模块内置模块中内置功能pow的帮助:

     

pow(x,y,z = None,/)       等效于x**y(带有两个参数)或x**y%z(带有三个参数)

Some types, such as ints, are able to use a more efficient algorithm when
invoked using the three argument form.

问题中提到的运算符源代码可能与您尝试使用的python版本的运算符不匹配。

答案 2 :(得分:1)

错误来自b = 2语句。

squared = list(map(partial(pow, b=2), range(10))

部分函数将关键字参数'b'传递给pow函数,由于pow()函数仅接受位置参数,因此会导致错误。有关更多信息,请参见help(pow)

但是,我在此调用中看到的另一个问题是部分函数以意外方式运行:

map(partial(pow, 2), range(10))

将按以下顺序生成结果:

[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

这表明部分函数实际上正在计算2^range(10)

如果您要对列表中的每个值求平方,我建议使用lambda函数简化代码:

b=2
test = map(lambda x: x**b, range(10))
print(list(test))

结果为:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

无需导入。

答案 3 :(得分:0)

pow作为库函数接受仅位置参数。因此,您可以按照以下步骤进行操作:

squared = list(map(partial(pow,2), range(10)))

关于您的其他问题,默认情况下,用户定义函数的参数为​​positional-or-keyword parameters,因此既可以用作常规参数也可以用作kw参数。当然,定义新​​功能pow可能会在以后引起混乱,尽管要小心。