我试图在Python中创建子类时了解*args**kwds的使用。

我想了解为什么这段代码会表现出这种方式。如果在对*args的调用中忽略了**kwdssuper().__init__,那么我会得到一些奇怪的参数。

这是我的测试用例:

class Animal(object):
    def __init__(self, moves, num_legs):
        self.moves = moves
        self.num_legs = num_legs

    def describe(self):
        print "Moves :{} , num_legs : {}".format(self.moves, self.num_legs)

class Snake(Animal):
    def __init__(self, poisonous, *args, **kwds):
        self.poisonous = poisonous
        print "I am poisonous:{}".format(self.poisonous)
        # This next line is key. You have to use *args , **kwds.
        # But here I have deliberately used the incorrect form,
        # `args` and `kwds`, and am suprised at what it does.
        super(Snake, self).__init__(args, kwds)

现在,当我创建Snake子类的实例时,该实例包含对super(…).__init__的错误调用(在这里我使用argskwds而不是*args**kwds),我得到了一些有趣的“参数解压缩”。

s1 = Snake(False, moves=True, num_legs=0)
s2 = Snake(poisonous=False, moves=True, num_legs=1)
s3 = Snake(False, True, 3)
s1.describe()
s2.describe()
s3.describe()

我得到的是:

Moves :() , num_legs : {'moves': True, 'num_legs': 0}
Moves :() , num_legs : {'moves': True, 'num_legs': 1}
Moves :(True, 3) , num_legs : {}

那么,为什么在s1s2中,__init__假定moves = Truenum_legs = 01是关键字参数,并将num_legs设置为dict?

s3中,它将两个变量作为元组解压缩到moves(在Animal类中)。

当我试图理解参数分解时,我偶然发现了这一点。抱歉,我不知道如何更好地解决这个问题。

最佳答案

Snake.__init__中,argspoisonous之后的所有位置参数的元组,而kwds是除poisonous之外所有关键字参数的字典。通过致电

super(Snake,self).__init__(args,kwds)

您将args中的moves分配给kwds,将num_legs分配给Animal.__init__。这就是您在输出中看到的。

前两个调用除了poisonous之外没有任何位置参数,因此args和相应的moves是一个空元组。第三次调用没有关键字参数,因此kwds和相应的num_legs是一个空dict。

10-06 05:19