2010-03-20 4 views
12

하위 클래스에서 재정의하려는 부모 클래스에 개인 메서드 def __pickSide(self):이 있습니다. 그러나 자식 클래스는 여전히 상속 된 def __pickSide(self):을 호출합니다. 함수를 재정의하려면 어떻게해야합니까? 하위 클래스의 함수 이름은 상위 함수의 이름과 완전히 같습니다.어떻게 부모 클래스의 함수를 파이썬으로 대체합니까?

+3

'__'을 모두 사용하지 마십시오. 그들은 혼란스러워. 실제로 파이썬에는 "개인"이 없습니다. 그들은 단순한 것을 혼란스럽게 만든다. 문제를 보여주는 가장 작은 코드 예제로 질문을 업데이트하십시오. –

+0

그게 내가 문제가되는 코드입니다 ... 뭘 더 원하니? 파이썬에서는 여전히 "개인"함수와 변수에 액세스 할 수 있지만 모든 공용 함수를 사용하지 않으면 클래스를 사용할 때 상황이 혼란 스럽습니다. – wrongusername

+0

"그게 코드예요?" 어떤 코드? 실제로 작동하지 않는 실제 코드 샘플을 실제로 제공하도록 질문을 업데이트 할 수 있습니까? 코드가 어떻게 생겼는지를 추측하는 것은 매우 어렵습니다. 물건을 사는 것은 쉽습니다. 잘못 추측하기 쉽습니다. "뭘 더 원하니?" 암호. 당신이 실제로 만들고있는 실수를보고보아야합니다. 내가 생각하는 실수가 아닙니다. –

답변

33

살펴 보자 :

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)으로 변경합니다. 즉, 함수가 정의 된 클래스에 따라 __pick 메서드 중 어떤 것이 호출되는지가 결정됩니다.

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

5

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

3
  • 은 당신이 필요할 때 액세스 더 많은 번거 로움을 만들기 위해 메소드의 이름을 미치게. 나는 결코 그들을 사용하지 않을 것을 권하고 싶다. 테스트와 같은 것을 더 부드럽게 만든다.

  • 파이썬에는 비공개가 존재하지 않으며, 존재한다면, 어쨌든 이것을 막을 수 있습니다. (이것은이 언어 개인 물건의 포인트입니다.)

  • 일반적인 규칙은 속성이 _foo처럼, 그것은 하나의 선도를 사용하는 클래스의 공용 인터페이스의 일부 밑줄없는 것을 나타 내기 위해서 (때문에) . 이는 공개 API에서 내부 세부 정보를 구분하는 코드를 작성하는 데 충분합니다.

관련 문제