Постарайтесь не определять все аргументы в подклассе

У меня есть класс:

class A(object):
    def __init__(self,a,b,c,d,e,f,g,...........,x,y,z)
        #do some init stuff

И у меня есть подкласс, которому нужен один дополнительный аргумент (последнее W)

class B(A):
    def __init__(self.a,b,c,d,e,f,g,...........,x,y,z,W)
        A.__init__(self,a,b,c,d,e,f,g,...........,x,y,z)
        self.__W=W

Это кажется немым для написания всего этого шаблонного кода, например, передающий весь args от BCtor к внутреннему вызову к Actor, с тех пор каждое изменение в Actor должен быть применен к двум другим местам в Bкод.

Я предполагаю, что Python имеет некоторую идиому для обработки таких случаев, о которых я не знаю. Можно ли указать на меня в правильном направлении?

Моя лучшая догадка, должна иметь своего рода Копию-Ctor для A и затем изменить код B в

class B(A):
     def __init__(self,instanceOfA,W):
         A.__copy_ctor__(self,instanceOfA)
         self.__W=W

Это удовлетворило бы моим потребностям, так как я всегда создаю подкласс при приведении пример родительского класса, Хотя я не уверен, возможно ли это...

19
задан olamundo 7 February 2010 в 04:34
поделиться

3 ответа

Учитывая, что аргументы могут передаваться как по имени, так и по позиции, я бы закодировал:

class B(A):
    def __init__(self, *a, **k):
      if 'W' in k:
        w = k.pop('W')
      else:
        w = a.pop()
      A.__init__(self, *a, **k)
      self._W = w
20
ответ дан 30 November 2019 в 04:11
поделиться

Хотите что-то вроде этого?

class A(object):
    def __init__(self, a, b, c, d, e, f, g):
        # do stuff
        print a, d, g

class B(A):
    def __init__(self, *args):
        args = list(args)
        self.__W = args.pop()
        A.__init__(self, *args)
0
ответ дан 30 November 2019 в 04:11
поделиться

Правка: основанный на предложении Мэтта, и для решения проблемы гнибблера - позиционно-аргументный подход; вы можете проверить, что дополнительный аргумент, специфичный для подкласса, указан - аналогично ответу Алекса :

class B(A):
  def __init__(self, *args, **kwargs):
    try:
      self._w = kwargs.pop('w')
    except KeyError:
      pass
    super(B,self).__init__(*args, **kwargs)

>>> b = B(1,2,w=3)
>>> b.a
1
>>> b.b
2
>>> b._w
3

оригинальный ответ:
. Та же идея, что и в ответе Мэтта , вместо него используется super().

Используйте super() для вызова метода superclass's __init__(), а затем продолжайте инициализацию подкласса:

class A(object):
  def __init__(self, a, b):
    self.a = a
    self.b = b

class B(A):
  def __init__(self, w, *args):
    super(B,self).__init__(*args)
    self.w = w
7
ответ дан 30 November 2019 в 04:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: