Подтвердить что ты не робот

Как переопределить конструктор класса Python со многими аргументами?

Скажем, у меня есть класс Foo, расширяющий класс Bar. И я хочу немного переопределить Foo consructor. И я не хочу даже знать, что такое подписание барных конструкторов. Есть ли способ сделать это?

Если вы не поняли, я имею в виду следующее:

class Bar:
   def __init__ (self, arg1=None, arg2=None, ... argN=None):
      ....


class Foo (Bar):
    #Here i just want add additional parameter to constructor, but don't want to know anything about Bar other parameters (arg1, arg2..., argN)
    def __init__ (self, my_new_arg=None, ??? )
       self.new_arg = my_new_arg
       Bar.__init__(self, ??? )

Есть ли способ поставить что-то короткое и элегантное вместо??? в этом коде? (Возможно, некоторые вариации args/kwargs)

4b9b3361

Ответ 1

class Parent(object):
    def __init__(self, a, b):
        print 'a', a
        print 'b', b

class Child(Parent):
    def __init__(self, c, d, *args, **kwargs):
        print 'c', c
        print 'd', d
        super(Child, self).__init__(*args, **kwargs)

test = Child(1,2,3,4)

Вывод:

c 1
d 2
a 3
b 4

Ответ 2

Решение *args, **kwds, представленное @Acorn, является хорошим началом (хотя я не согласен с частью ответа *args). Этот подход представлен рядом уточнений в статье: Python Super рассмотренный супер.

Часть *args не рекомендуется, так как она не позволяет вставлять новые классы в иерархию и исключает использование подклассами из нескольких наследований с другими классами, которые могут иметь несовместимые позиционные аргументы. Подход **kwds работает намного лучше, потому что он не обеспечивает конкретного заказа цепочек вызовов.

Также обратите внимание: вы можете использовать именованные аргументы для разделения и удаления текущего метода с аргументами из остальных аргументов ключевого слова, прежде чем они пройдут цепочку:

class Bar(object):
   def __init__(self, arg1=None, arg2=None, argN=None):
       print arg1, arg2, argN

class Foo(Bar):
    def __init__(self, my_new_arg=None, **kwds):
       super(Foo, self).__init__(**kwds)
       self.new_arg = my_new_arg
       print my_new_arg

f = Foo(my_new_arg='x', arg2='y')

Наличие каждого метода для исключения аргументов, которые ему нужны, важно, потому что родительский метод, такой как object.__init__, не ожидает никаких аргументов.

Наконец, если вы собираетесь использовать super, убедитесь, что ваш самый верхний класс - это новый стиль (т.е. он наследует объект или какой-либо другой встроенный тип).