我试图在Python中创建子类时了解*args
和**kwds
的使用。
我想了解为什么这段代码会表现出这种方式。如果在对*args
的调用中忽略了**kwds
和super().__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__
的错误调用(在这里我使用args
和kwds
而不是*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 : {}
那么,为什么在
s1
和s2
中,__init__
假定moves = True
和num_legs = 0
或1
是关键字参数,并将num_legs
设置为dict?在
s3
中,它将两个变量作为元组解压缩到moves
(在Animal
类中)。当我试图理解参数分解时,我偶然发现了这一点。抱歉,我不知道如何更好地解决这个问题。
最佳答案
在Snake.__init__
中,args
是poisonous
之后的所有位置参数的元组,而kwds
是除poisonous
之外所有关键字参数的字典。通过致电
super(Snake,self).__init__(args,kwds)
您将
args
中的moves
分配给kwds
,将num_legs
分配给Animal.__init__
。这就是您在输出中看到的。前两个调用除了
poisonous
之外没有任何位置参数,因此args
和相应的moves
是一个空元组。第三次调用没有关键字参数,因此kwds
和相应的num_legs
是一个空dict。