在查找一些pyQt示例时,我遇到了以下类型的代码:
class DisplayPage(QWizardPage):
def __init__(self, *args):
apply(QWizardPage.__init__, (self, ) + args)
* args是什么意思?
使用此类代码申请的目的是什么?
答案 0 :(得分:10)
*args
表示__init__
接受任意数量的位置参数,所有这些参数都将存储在列表args
中。有关详情,请参阅What does *args and **kwargs mean?
这段代码使用已弃用的apply
函数。现在你可以用以下三种方式之一来写这个:
QWizardPage.__init__(self, *args)
super(DisplayPage, self).__init__(*args)
super().__init__(*args)
第一行是apply
所做内容的字面翻译(在这种情况下不要使用它,除非QWizardPage
不是new-style class)。第二个使用super
中定义的PEP 367。第三个使用super
中定义的PEP 3135(仅适用于Python 3.x)。
答案 1 :(得分:3)
DisplayPage
继承自QWizardPage
。它的构造函数接受可变数量的参数(这是* args的意思),并将它们全部传递给它的父元素的构造函数QWizardPage
最好说:
super(DisplayPage, self).__init__(*args)
答案 2 :(得分:1)
“可变长度参数列表”:http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
基本上,它只是说,将所有传递给DisplayPage的__init__方法的参数传递给QWizardPage的__init__方法。
答案 3 :(得分:0)
在参数列表中(定义函数)* args是Python表示“变量参数”的方式(在C和C语言中称为“varargs”)。在一个参数列表中(调用一个函数)* args具有互补意义......它将函数“应用”到变量的值,好像它们已被解包并“粘贴”一样进入函数的调用。
“参数”和“参数”之间的区别是经常没有阐明的。参数是放置参数的槽。参数提供给函数调用。参数是可以在函数范围内引用参数的名称。
所以如果我定义一个函数:
def foo(x, *a):
print "First arg: ", x
print "Other args: ", ' '.join([str(x) for x in a])
我可以这么称呼它:
foo(1, 2, 3, 4)
...我的代码将1视为“x”(参数是对整数1的对象引用,绑定到名为“x”的参数),列表[2,3,4]为(参数将是对三项列表的对象引用,并绑定到名为“a”的函数参数。
如果我绑定以下元组:
bar = (1, 2, 3, 4)
...然后致电foo()
:
foo(*bar)
...这将是一个与我之前的例子相同的电话。 “bar”将被解压缩,并作为4个参数的序列传递给foo()
。此特定函数将1绑定到第一个参数,并将任意数量的其他参数打包到a参数中。但是我可以调用其他功能:
geewhiz(*bar)
...就像我在foo()
中所描述的那样传递四个参数。 (如果geewhiz()
被编写为只接受3个参数,则Python将引发TypeError以调用具有错误参数数量的函数...就像调用geewhiz(1,2,3,4)
时一样。
一般来说,Python支持定义使用默认参数,可变数量的参数和关键字参数的函数比我见过的任何其他脚本语言更灵活。然而,所有这些力量和灵活性可能会有点混乱。
在Python3中,他们还为包装分配添加了一些皱纹。元组包装分配如下:
a, b = 1, 2
...并且还经常出现在以下代码中:
for key, val in my_dict.items():
...
每个项目都由.items()
方法作为元组返回,并被打包到密钥val元组中。 (Python中的元组不需要括起括号。,是元组标记)。
现在在Python3中可以做到这样的事情:
a, *b = 1, 2, 3, 4
...正如您可能猜到的那样,将第一个元素绑定到“a”,其余元素被打包到另一个绑定到“b”的元组中。
虽然这与函数参数列表中的* args无关,但我提到它是因为它们在概念和语法上相似。