복붙노트

[PYTHON] 하위 클래스에서 모든 인수를 지정하지 마십시오.

PYTHON

하위 클래스에서 모든 인수를 지정하지 마십시오.

수업이 있습니다.

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

그리고 나는 하나의 추가 arg (마지막 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

이 모든 보일러 - 플레이트 코드를 작성하는 것은 바보 같이 보입니다. 예를 들어, B의 Ctor에서 내부 호출을 A의 ctor로 전달하면 A의 ctor를 변경할 때마다 B 코드의 다른 두 위치에 적용해야합니다.

나는 파이썬이 내가 알지 못하는 그러한 사례들을 다루기위한 관용구를 가지고 있다고 생각한다. 올바른 방향으로 나를 가리킬 수 있습니까?

최선의 방법은 A에 대해 Copy-Ctor를 사용하고 B의 코드를 다음과 같이 변경하는 것입니다.

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

아버지 클래스의 인스턴스가 주어지면 항상 하위 클래스를 만들므로 내 필요에 맞을 것입니다. 가능한지 확실하지 않지만 ...

해결법

  1. ==============================

    1.인수가 이름 또는 위치로 전달 될 수 있다고 생각하면 코드를 작성합니다.

    인수가 이름 또는 위치로 전달 될 수 있다고 생각하면 코드를 작성합니다.

    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
    
  2. ==============================

    2.편집 : 매트의 제안을 토대로하고, 뉘 블러의 관심사를 위치 인수 접근법으로 해결합니다. Alex의 대답과 비슷한 추가 하위 클래스 지정 인수가 지정되었는지 확인할 수 있습니다.

    편집 : 매트의 제안을 토대로하고, 뉘 블러의 관심사를 위치 인수 접근법으로 해결합니다. Alex의 대답과 비슷한 추가 하위 클래스 지정 인수가 지정되었는지 확인할 수 있습니다.

    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 ()를 사용하여 수퍼 클래스의 __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
    
  3. ==============================

    3.인수의 일부 또는 전부가 __init__에 전달되는 경우, 서브 클래스에서 __init__ 메소드 서명을 반복하는 것을 피하는 것이 유용 할 수 있습니다.

    인수의 일부 또는 전부가 __init__에 전달되는 경우, 서브 클래스에서 __init__ 메소드 서명을 반복하는 것을 피하는 것이 유용 할 수 있습니다.

    이러한 경우, __init__은 다른 메소드에 다른 인수를 전달할 수 있으며, 서브 클래스는 다음을 재정의 할 수 있습니다.

    class A(object):
        def __init__(self, a=1, b=2, c=3, d=4, *args, **kwargs):
            self.a = a
            self.b = b
            # …
            self._init_extra(*args, **kwargs)
    
        def _init_extra(self):
            """
            Subclasses can override this method to support extra
            __init__ arguments.
            """
    
            pass
    
    
    class B(A):
        def _init_extra(self, w):
            self.w = w
    
  4. ==============================

    4.이런 식으로하고 싶니?

    이런 식으로하고 싶니?

    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)
    
  5. from https://stackoverflow.com/questions/2215923/avoid-specifying-all-arguments-in-a-subclass by cc-by-sa and MIT license