python 继承和 __init__ 函数
我在寻找一些 pyQt 示例时遇到了以下类型的代码:
class DisplayPage(QWizardPage):
def __init__(self, *args):
apply(QWizardPage.__init__, (self, ) + args)
*args 是什么意思?
使用 apply 此类代码的目的是什么?
I came across the folloqing type of code when looking for some pyQt examples :
class DisplayPage(QWizardPage):
def __init__(self, *args):
apply(QWizardPage.__init__, (self, ) + args)
What does *args mean ?
What is the purpose of using apply for this type of code ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
*args
表示__init__
接受任意数量的位置参数,所有这些都将存储在args
列表中。有关详细信息,请参阅*args 和 **kwargs 是什么意思?< /em>这段代码使用了已弃用的
apply
函数。现在,您可以用以下三种方式之一来编写它:
第一行是
apply
功能的字面翻译(在这种情况下不要使用它,除非QWizardPage
不是新样式类)。第二个使用super
,如 PEP 367。第三个使用super
中定义的PEP 3135(仅适用于 Python 3.x)。*args
means that__init__
takes any number of positional arguments, all of which will be stored in the listargs
. For more on that, see What does *args and **kwargs mean?This piece of code uses the deprecated
apply
function. Nowadays you would write this in one of three ways:The first line is a literal translation of what
apply
does (don't use it in this case, unlessQWizardPage
is not a new-style class). The second usessuper
as defined in PEP 367. The third usessuper
as defined in PEP 3135 (works only in Python 3.x).DisplayPage
继承自QWizardPage
。它的构造函数接受可变数量的参数(这就是 *args 的含义),并将它们全部传递给其父级 QWizardPage 的构造函数,最好这样说:
DisplayPage
inherits fromQWizardPage
. Its constructor accepts a variable amount of arguments (which is what *args means), and passes them all to the constructor of its parent,QWizardPage
It's better to say:
“可变长度参数列表”: http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
基本上,它只是说,采取所有的论点传递给 DisplayPage 的 __init__ 方法并将它们传递给 QWizardPage 的 __init__ 方法。
"Variable length argument lists": http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
Basically, it's just saying, take all the arguments that were passed to DisplayPage's __init__ method and pass them to QWizardPage's __init__ method.
在参数列表(函数的定义)中,*args 是 Python 表示“可变参数”的方式(在 C 和类 C 语言中称为“varargs”)。在参数列表(调用函数)中,*args 具有互补的含义...它将函数“应用”到变量的值,就好像它们已被解压并“粘贴”一样进入函数的调用。
“参数”和“参数”之间的这种区别通常没有被阐明。参数是放置参数的槽。参数被提供给函数调用。参数是可以在函数范围内引用参数的名称。
因此,如果我定义一个函数:
我可以这样调用它:
...我的代码会将 1 视为“x”(参数是对整数 1 的对象引用,绑定到名为“x”的参数)和列表[2,3,4] 作为 a (参数将是对三项列表的对象引用,并绑定到名为“a”的函数参数)。
如果我绑定以下元组:
... 并因此调用
foo()
:... 这将是与我之前的示例相同的调用。 “bar”将被解包,并作为 4 个参数的序列传递给 foo() 。这个特定的函数会将 1 绑定到第一个参数,并将任意数量的其他参数打包到 a 参数中。不过,我可以调用其他一些函数:
...并且它将传递四个参数,就像我为
foo()
描述的那样。 (如果geewiz()
被编写为只接受 3 个参数,那么 Python 将引发一个 TypeError,因为调用参数数量错误的函数......就像调用geewiz( 1,2,3,4)
一般来说,Python 对定义采用默认参数、可变数量参数和关键字参数的函数的支持比我见过的任何其他脚本语言都更灵活。并且灵活性可能有点令人困惑。
在 Python3 中,他们还为元组打包分配添加了一些皱纹,元组打包分配看起来像:
... 并且也经常出现在如下代码中:
每个项目都由 < 返回。 code>.items() 方法作为元组,并打包到键 val 元组中(Python 中的元组不需要括号。, 是元组标记。 )。
现在在Python3中可以做这样的事情:
...,正如你可能猜到的那样,将第一个元素绑定到“a”,并将其余元素打包到另一个绑定到“b”的元组中
。与函数参数列表中的 *args 无关我提到它是因为它们在概念和语法上相似。
In a parameter list (definition of a function) *args is Python's way of representing "variable arguments" (called "varargs" in C and C like languages). In an argument list (a call to a function) *args has the complementary meaning ... it "applies" the function to the value of the variable as if they'd been unpacked and "pasted" into the function's call.
This distinction between "parameters" and "arguments" is one that's often not elucidated. A parameter is a slot into which arguments are placed. Arguments are supplied to a function call. Parameters are the names by which arguments can be referred from within the scope of the function.
So if I define a function:
I can call it thus:
... and my code will see 1 as "x" (the argument is an object reference to the integer 1, bound to the parameter named "x") and the list [2,3,4] as a (the argument will be an object reference to a three item list and bound to the function's parameter named "a").
If I bind the following tuple:
... and call
foo()
thus:... it will be a call that's identical to my previous example. "bar" will be unpacked, and passed to
foo()
as a sequence of 4 arguments. This particular function would bind 1 to the first parameter and pack any number of other arguments into the a parameter. However I could call some other function:... and it would be passed four arguments just as I described for
foo()
. (Ifgeewhiz()
was written to take only 3 arguments then Python will raise a TypeError for calling a function with the wrong number of arguments ... exactly as it would if you calledgeewhiz(1,2,3,4)
.In general Python's support for defining functions taking defaulted arguments, variable numbers of arguments, and keyword arguments is more flexible than any other scripting language I've ever seen. However all that power and flexibility can be a bit confusing.
In Python3 they've also added some wrinkles to tuple packing assignments. Tuple packing assignments look like:
... and also show up frequently in code like:
Each of the items is being returned by the
.items()
method as a tuple, and being packed into the key, val tuple. (Tuples in Python don't require enclosing parentheses. The , is the tuple-token).Now in Python3 it's possible to do something like this:
... which, as you might guess, binds the first element to "a" and the rest are packed into another tuple which is bound to "b."
While this really isn't related to *args in function parameter lists I mention it because they are conceptually and syntactically similar.