복붙노트

[PYTHON] 파이썬에서 개인 및 보호 된 메소드의 상속

PYTHON

파이썬에서 개인 및 보호 된 메소드의 상속

나도 알아, 파이썬에서 '실제'개인 / 보호 된 방법은 없습니다. 이 방법은 아무 것도 숨기위한 것이 아닙니다. 파이썬이 무엇을하는지 이해하고 싶습니다.

class Parent(object):
    def _protected(self):
        pass

    def __private(self):
        pass

class Child(Parent):
    def foo(self):
        self._protected()   # This works

    def bar(self):
        self.__private()    # This doesn't work, I get a AttributeError:
                            # 'Child' object has no attribute '_Child__private'

그렇다면이 '보호 된'메소드가 상속되지만 '개인'은 전혀 사용되지 않는다는 의미입니다. 또는 나는 무엇이라도 놓쳤 느냐?

해결법

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

    1.파이썬에는 프라이버시 모델이 없으며 C ++, C # 또는 Java와 같은 액세스 수정 자도 없습니다. 진정으로 '보호 된'또는 '개인적인'속성은 없습니다.

    파이썬에는 프라이버시 모델이 없으며 C ++, C # 또는 Java와 같은 액세스 수정 자도 없습니다. 진정으로 '보호 된'또는 '개인적인'속성은 없습니다.

    맨 앞의 두 개의 밑줄과 밑줄이없는 밑줄이있는 이름은 상속 될 때 충돌로부터 보호하기 위해 맹 글링됩니다. 하위 클래스는 자체 __private () 메서드를 정의 할 수 있으며 상위 클래스의 동일한 이름을 간섭하지 않습니다. 이러한 이름은 private 클래스로 간주됩니다. 그들은 여전히 ​​수업 외부에서 접근 가능하지만 우연히 충돌 할 확률이 훨씬 적습니다.

    매글 링은 이름에 여분의 밑줄과 클래스 이름 (이름이 사용되는 방법이나 존재하는 경우에 관계없이)을 앞에 붙여서 효과적으로 네임 스페이스를 부여함으로써 수행됩니다. Parent 클래스에서 __private 식별자는 컴파일 타임에 _Parent__private로 대체되고 Child 클래스에서는 식별자가 _Child__private로 대체되며 클래스 정의의 모든 곳에서 사용됩니다.

    다음과 같이 작동합니다.

    class Child(Parent):
        def foo(self):
            self._protected()
    
        def bar(self):
            self._Parent__private()
    

    어휘 분석 문서의 식별자의 예약 클래스를 참조하십시오.

    이름에 대한 참조 문서 :

    특정 이름을 사용할 수 없거나 클래스를 깨뜨릴 위험이있는 클래스를 서브 클래스로 만들려는 개발자에게 말하지 않아도되는 경우를 제외하고는 클래스 개인 이름을 사용하지 마십시오. 게시 된 프레임 워크와 라이브러리 외에는이 기능을 거의 사용하지 않습니다.

    PEP 8 Python 스타일 가이드는 개인 이름 맹 글링에 대해 이렇게 말합니다.

  2. ==============================

    2.또한 PEP8에 의하면

    또한 PEP8에 의하면

    국제 대회에서 너무 멀리 떨어져 있어야합니다. 내 말은 네가 그들을 사적으로 취급해야한다는 의미 야.

  3. ==============================

    3.double __ 속성은 _ClassName__method_name으로 변경되어 _method_name이 의미하는 의미 프라이버시보다 더 사적인 것입니다.

    double __ 속성은 _ClassName__method_name으로 변경되어 _method_name이 의미하는 의미 프라이버시보다 더 사적인 것입니다.

    기술적으로는 여전히 원한다면 여전히 접근 할 수 있지만 아마 아무도 그렇게하지 않을 것입니다. 따라서 코드 추상화의 이유를 유지하기 위해서는 그 시점에서 메서드가 비공개가 될 수도 있습니다.

    class Parent(object):
        def _protected(self):
            pass
    
        def __private(self):
            print("Is it really private?")
    
    class Child(Parent):
        def foo(self):
            self._protected()
    
        def bar(self):
            self.__private()
    
    c = Child()
    c._Parent__private()
    

    이것은 메소드가 하위 클래스 메소드 이름과 충돌하지 않도록 허용하는 추가적인 장점을 가지고있다.

  4. ==============================

    4.데이터 멤버를 비공개로 선언하면

    데이터 멤버를 비공개로 선언하면

    __은밀한()

    클래스 외부에서 액세스 할 수 없습니다.

    파이썬은 name mangling이라는 기술을 지원합니다.

    이 기능은 두 개의 밑줄이있는 클래스 멤버를 다음과 같이 바꿉니다.

    Child ()에서 액세스하려면 다음을 사용할 수 있습니다. self._Parent__private ()

  5. ==============================

    5.이것은 오래된 질문이지만, 나는 그것을 만났고 좋은 해결 방법을 발견했다.

    이것은 오래된 질문이지만, 나는 그것을 만났고 좋은 해결 방법을 발견했다.

    보호 된 함수를 모방하고 싶지만 여전히 하위 클래스에서 쉽게 함수에 액세스하려고했기 때문에 부모 클래스에서 맹 글링 된 경우 이름을 지정합니다.

    parent_class_private_func_list = [func for func in dir(Child) if func.startswith ('_Parent__')]
    
    for parent_private_func in parent_class_private_func_list:
            setattr(self, parent_private_func.replace("_Parent__", "_Child"), getattr(self, parent_private_func))        
    

    아이디어는 수동으로 부모 함수 이름을 현재 네임 스페이스에 맞는 것으로 바꾸는 것입니다. 자식 클래스의 init 함수에이를 추가 한 후에는 쉽게 함수를 호출 할 수 있습니다.

    self.__private()
    
  6. ==============================

    6.AFAIK, 두 번째 경우 Python은 "name mangling"을 수행하므로 부모 클래스의 __private 메소드의 이름은 실제로 다음과 같습니다.

    AFAIK, 두 번째 경우 Python은 "name mangling"을 수행하므로 부모 클래스의 __private 메소드의 이름은 실제로 다음과 같습니다.

    _Parent__private
    

    그리고 당신은이 형태로 아이에게 사용할 수 없습니다.

  7. from https://stackoverflow.com/questions/20261517/inheritance-of-private-and-protected-methods-in-python by cc-by-sa and MIT license