python 호출 부모 클래스의 함수를 파이썬으로 재정의하려면 어떻게해야합니까?




파이썬 오버라이딩 (3)

개인 메서드 def __pickSide(self): 부모 클래스에서 자식 클래스에서 재정의하고 싶습니다. 그러나 자식 클래스는 여전히 상속 된 def __pickSide(self): 호출합니다. 어떻게 함수를 오버라이드 할 수 있습니까? 하위 클래스의 함수 이름은 상위 함수의 이름과 완전히 동일합니다.


당신이보고있는 문제는 이중 밑줄이 호출에서도 함수 이름을 조작한다는 것입니다. 이렇게하면 다형성이 제대로 작동하지 않습니다. 왜냐하면 변형 된 이름은 메서드가 정의 된 클래스의 이름을 기반으로하고 참조되는 개체의 클래스 이름을 기반으로하지 않기 때문입니다. 이중 밑줄을 다른 것으로 바꾸면이 문제를 해결할 수 있습니다.


가장 쉬운 예를 살펴 보겠습니다.

from dis import dis

class A(object):
  def __pick(self):
      print "1"

  def doitinA(self):
      self.__pick()

class B(A):
  def __pick(self):
      print "2"

  def doitinB(self):
      self.__pick()

b = B()
b.doitinA() # prints 1
b.doitinB() # prints 2

dis(A.doitinA)
print
dis(B.doitinB)

해체는 다음과 같습니다.

  8           0 LOAD_FAST                0 (self)
              3 LOAD_ATTR                0 (_A__pick)
              6 CALL_FUNCTION            0
              9 POP_TOP
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE

 15           0 LOAD_FAST                0 (self)
              3 LOAD_ATTR                0 (_B__pick)
              6 CALL_FUNCTION            0
              9 POP_TOP
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE

보시다시피, 파이썬은 클래스 이름을 포함하는 이름 (이 경우 _A__pick_B__pick )에 두 개의 밑줄 (그리고 그러한 이름에 대한 액세스!)로 시작하는 함수 이름을 _B__pick 합니다. 즉, 함수가 정의 된 클래스에 따라 __pick 메서드 중 어떤 것이 호출되는지가 결정됩니다.

해결책은 간단합니다. 이중 밑줄을 제거하여 의사 개인 메서드를 피하십시오. 예를 들어, _pick 대신 _pick 사용 __pick .


  • __foo 이름을 사용하면 __foo 이름을 변경하여 __foo 에 따라 메서드에 액세스 할 수 있습니다. 나는 결코 테스트를 사용하는 것을 권장하지 않을 것입니다.

  • 파이썬에는 프라이빗 프라이빗은 존재하지 않으며, 존재한다면, 당신이 이것을 어떻게해서든지하지 못하게 할 것입니다. (이것이 사적인 물건의 언어입니다.)

  • 속성이 _foo 와 같은 단일 밑줄 을 사용하는 클래스의 공용 인터페이스의 일부가 아니라는 것을 나타내는 일반적인 규칙입니다. 내부 API를 공개 API와 분리하여 코드를 명확하게 작성하는 데 충분합니다.





parent