[python] Python의 “Private”(구현) 클래스

두 부분으로 구성된 작은 Python 모듈을 코딩하고 있습니다.

  • 공용 인터페이스를 정의하는 일부 함수,
  • 위 함수에서 사용하는 구현 클래스이지만 모듈 외부에서는 의미가 없습니다.

처음에는이 구현 클래스를 사용하는 함수 내부에 정의하여 “숨기기”로 결정했지만 이로 인해 가독성이 떨어지고 여러 함수가 동일한 클래스를 재사용하는 경우 사용할 수 없습니다.

그래서 주석과 독 스트링 외에도 클래스를 “비공개”또는 “내부”로 표시하는 메커니즘이 있습니까? 밑줄 메커니즘을 알고 있지만 이해하기 때문에 변수, 함수 및 메서드 이름에만 적용됩니다.



답변

단일 밑줄 접두사를 사용합니다.

class _Internal:
    ...

이것은 ‘내부’기호에 대한 공식 파이썬 규칙입니다. “from module import *”는 밑줄 접두사가 붙은 개체를 가져 오지 않습니다.

편집 : 단일 밑줄 규칙 에 대한 참조


답변

요컨대 :

  1. 개인 정보를 보호 할 수 없습니다 . Python에는 비공개 클래스 / 메서드 / 함수가 없습니다. 적어도 Java와 같은 다른 언어 에서처럼 엄격한 개인 정보 보호는 아닙니다.

  2. 개인 정보 보호만을 표시 / 제안 할 수 있습니다 . 이것은 관례를 따릅니다. 클래스 / 함수 / 메서드를 비공개로 표시하는 파이썬 규칙은 앞에 _ (밑줄)을 붙이는 것입니다. 예를 들어, def _myfunc()또는 class _MyClass:. 또한 두 개의 밑줄 (예 :)을 사용하여 메서드를 시작하여 의사 개인 정보를 만들 수도 있습니다 __foo. 메서드에 직접 액세스 할 수는 없지만 클래스 이름 (예 :)을 사용하는 특수 접두사를 통해 여전히 호출 할 수 있습니다 _classname__foo. 따라서 귀하가 할 수있는 최선은 개인 정보 보호를 강요하는 것이 아니라 표시 / 제안하는 것입니다.

파이썬은이 점에서 펄과 같습니다. Perl 책에서 프라이버시에 관한 유명한 대사를 바꿔 말하면, 철학은 당신이 초대받지 않았기 때문에 거실에서 나가야한다는 것입니다.

자세한 내용은:


답변

__all__내보낼 이름 목록 인을 정의합니다 ( 문서 참조 ).

__all__ = ['public_class'] # don't add here the 'implementation_class'


답변

내가 가끔 사용하는 패턴은 다음과 같습니다.

클래스 정의 :

class x(object):
    def doThis(self):
        ...
    def doThat(self):
        ...

클래스의 인스턴스를 만들고 클래스 이름을 덮어 씁니다.

x = x()

기능을 노출하는 기호를 정의하십시오.

doThis = x.doThis
doThat = x.doThat

인스턴스 자체를 삭제합니다.

del x

이제 공용 함수 만 노출하는 모듈이 있습니다.


답변

규칙은 내부 클래스, 함수 및 변수 앞에 “_”를 추가합니다.


답변

디자인 관습의 문제를 다루기 위해 크리스토퍼가 말했듯이 파이썬에는 “비공개”와 같은 것이 없습니다. 이것은 C / C ++ 배경에서 온 누군가에게는 왜곡 된 것처럼 들릴 수 있지만 (예를 들어, 저처럼) 결국에는 다음 규칙이 충분하다는 것을 알게 될 것입니다.

앞에 밑줄이있는 것을 보는 것은 그것을 직접 사용하지 않기에 충분한 힌트가 될 것입니다. 복잡한 help(MyClass)출력 (모든 사람이 클래스 사용 방법을 검색 할 때 보는 것임)에 관심이 있다면 밑줄이있는 속성 / 클래스가 여기에 포함되지 않으므로 “공용”인터페이스 만 설명하게됩니다.

또한 모든 것을 공개하는 것은 그 자체로 멋진 특전을 가지고 있습니다. 예를 들어 외부에서 거의 모든 것을 단위 테스트 할 수 있습니다 (C / C ++ 비공개 구문으로는 실제로 할 수 없음).


답변

“개인”식별자의 이름 앞에 두 개의 밑줄을 사용합니다. 모듈의 클래스의 경우 단일 선행 밑줄을 사용하고 “from module import *”를 사용하여 가져 오지 않습니다.

class _MyInternalClass:
    def __my_private_method:
        pass

(Python에는 진정한 “private”와 같은 것은 없습니다. 예를 들어, Python은 자동으로 이중 밑줄이있는 클래스 멤버의 이름을으로 변경합니다 __clssname_mymember. 따라서 변경된 이름을 알고 있다면 어쨌든 “private”엔티티를 사용할 수 있습니다. . 여기를 참조하십시오. 물론 원하는 경우 “내부”클래스를 수동으로 가져 오도록 선택할 수 있습니다.