2010-05-04 2 views
2

Это не результат я ожидаю увидеть:классы Python Новый стиль и супер функция

class A(dict): 
    def __init__(self, *args, **kwargs): 
     self['args'] = args 
     self['kwargs'] = kwargs 

class B(A): 
    def __init__(self, *args, **kwargs): 
     super(B, self).__init__(args, kwargs) 

print 'Instance A:', A('monkey', banana=True) 
#Instance A: {'args': ('monkey',), 'kwargs': {'banana': True}} 

print 'Instance B:', B('monkey', banana=True) 
#Instance B: {'args': (('monkey',), {'banana': True}), 'kwargs': {}} 

Я просто пытаюсь получить классы A и B имеют согласованные значения, установленные. Я не уверен, почему kwargs вставляются в args, но я должен предположить, что я либо вызываю __init__() неправильно из подкласса, либо я пытаюсь сделать то, что вы просто не можете сделать.

Любые советы?

ответ

14

Попробуйте вместо этого:

super(B, self).__init__(*args, **kwargs) 

Поскольку функция инициализации для A ожидает фактических арг/kwargs (а не только два аргумента), то есть на самом деле передать его распакованные версии арг/kwargs так, что они будут переупакованы должным образом.

В противном случае уже упакованный список аргументов и dict kwargs будет перефабрифицирован как просто список args с двумя элементами и пустой kwargs dict из-за того, что вы передаете список и dict , вместо фактических неназванных и именованных параметров.

+0

omg ничего себе. теперь я чувствую себя глупо. был это * это * простой !!? да! это сработало! Спасибо большое! – jedmao

2

В то время как я полностью согласен с Давом, знаете ли вы, что если __init__ B не имеет другой цели, кроме вызова его супер, вы можете спокойно опустить его? Я имею в виду, что с вашими примерами вы можете просто определить B как

>>> class B(A): 
...  pass 
+1

да. Я знаю об этом. Спасибо. Однако я хотел расширить функциональность __init__. – jedmao

Смежные вопросы