Discuss / Python / 新人的一点思考点。

新人的一点思考点。

Topic source

import functools def test(a=1,b=2): return a + b test() #默认参数结果是3 test(5,6) #传入参数结果是11

new_test = functools.partial(test,a=3,b=4) #偏函数重新修改参数 new_test() #这里结果是7没问题 new_test(7,8) 这里会报错:TypeError: test() got multiple values for argument 'a'

只有重新带参数设定值才能正常运行,例如: new_test(a=7,b=8) 相当于: kw = {'a':7,'b':8} test(**kw)

意思就是:如果用了偏函数固定了参数a,b的值,那么这个a,b两个参数在新函数里就不能当作默认参数来使用,必须要带参数名修改值一起传入才行。

gd83594394

#2 Created at ... [Delete] [Delete and Lock User]

同是新人,觉得你这个问题其实是一个挺大的坑。

我看了Python的文档,里面提到传递到偏函数的位置参数和可变参数,是以追加append的方式加入到原来的函数里面,所以我猜测之所以会出现你所说的问题,是因为对a和b重复赋予了多个值,并且应该是先赋予了(7,8)然后又以默认值再赋予了一次,所以就报错:got multiple values for argument。

不过有意思的是,这个got multiple values for argument的错误提示信息,和takes from 0 to 1 positional arguments but 2 were given却是两种不同的类型,按我的理解,似乎前者是重复赋值,而后者则识别为多余的值,这里面不清楚到底Python是按什么规则的????

还有一个也挺有意思的,我猜测你的是在Python2.4里面运行的代码?因为我在Python3.4里面运行的代码报错信息是TypeError: test() got multiple values for argument 'b',而你是a,这点我没有去在2.4里面证实,不过我看国外有些讨论似乎是有这个类似的说法的???

@莉莉娅的小暖炉

new_test(7, 8)

这等价于 test(7, 8, a=3, b=4),同一个参数赋了多个值当然会报错。

new_test(a=7, b=8)

如果你传入的是键值参数的话,functools.partial 会把传入的键值覆盖到创建 functools.partial 时提供的键值上。 所以这等价于 test(a=7, b=8)

@gd83594394

TypeError: test() got multiple values for argument 'a' 发生在对一个参数重复赋值的情况下,比如 test(1, 2, a=3) 这里对 a 同时附了 1 和 3两个值,Python 检测到这点后报错。

TypeError: test() takes from 0 to 2 positional arguments but 3 were given 发生了传入的参数超过了函数能接受的参数上限,比如 test(1, 2, 3),这里 test() 最多能接受 2 个参数,但是传入了 3 个,Python 检测到这点后报错。

jhbbbbbbbbbbb

#4 Created at ... [Delete] [Delete and Lock User]

改为new_test=funtools.partial(test,3,4)就可以了,哪位大神解释下呢?

千羽王爵

#5 Created at ... [Delete] [Delete and Lock User]

@jhbbbbbbbbbbb 你这是什么版本的,我是3.6.4,模块名是"functools",然后我会报错:TypeError: test() takes from 0 to 2 positional arguments but 4 were given.


  • 1

Reply