>  기사  >  백엔드 개발  >  Python 단일 밑줄/이중 밑줄 사용법 요약

Python 단일 밑줄/이중 밑줄 사용법 요약

巴扎黑
巴扎黑원래의
2016-12-08 11:17:591833검색

Python은 밑줄을 변수 접두사 및 접미사로 사용하여 특수 변수/메서드를 지정합니다.

네 가지 주요 상황이 있습니다
1. 1. object # public
2. __object__ # 특수, Python 시스템 사용, 사용자가 그렇게 정의해서는 안 됩니다
3. __object # private (이름 런타임 중 맹글링)
4. _object # 파이썬 코딩 규칙을 따르고 비공개로 간주합니다.
핵심 스타일: 변수 이름의 시작 부분에 밑줄을 사용하지 마세요.

밑줄은 인터프리터에게 특별한 의미를 가지며 내장 식별자에서 사용되는 기호이므로 프로그래머는 변수 이름의 시작 부분에 밑줄을 사용하지 않는 것이 좋습니다. 일반적으로 변수 이름 _object는 "private"으로 간주되어 모듈이나 클래스 외부에서 사용할 수 없으며 'from moduleimport *'를 사용하여 가져올 수 없습니다. 변수가 비공개인 경우 _object를 사용하여 변수를 나타내는 것이 좋습니다. 변수 이름 __object__는 Python에서 특별한 의미를 갖기 때문에 일반 변수에는 이 명명 스타일을 피해야 합니다.
"단일 밑줄"로 시작하는 멤버 변수를 보호된 변수라고 합니다. 이는 클래스 개체와 하위 클래스 개체 자체만 이러한 변수에 액세스할 수 있음을 의미합니다. "이중 밑줄"로 시작하는 멤버 변수는 전용 멤버입니다. 즉, 클래스 객체 자체만 액세스할 수 있으며 하위 클래스 객체도 이 데이터에 액세스할 수 없습니다. (아래 참조)
단일 밑줄(_foo)로 시작하는 것은 클래스에서 제공하는 인터페이스를 통해 액세스해야 하며 "from xxx import *"를 사용하여 가져올 수 없는 클래스 속성을 나타냅니다. 이중 밑줄로 시작하는(__foo)는 클래스의 전용 멤버를 나타냅니다. 이중 밑줄로 시작하고 끝나는(__foo__)는 클래스의 생성자를 나타내는 __init__()와 같이 Python의 특수 메서드별 식별을 나타냅니다.

1.class Foo():

2. def __init__():
3.
4. def public_method():
6.           '공개 방법입니다' 인쇄                                                                                   def _halfprivate_method():
12. '이것은 하나의 밑줄 표시 방법입니다'를 인쇄합니다.
Foo의 객체를 인스턴스화합니다.

f = Foo ()
1.f.public_method () # OK
2.
3.f.__fullprivate_method() # 오류 발생
5.f._halfprivate_method() 🎜>6. ._Foo__fullprivate()_method() # OK

위의 예에서 볼 수 있듯이 f._halfprivate_method()는 실제로 직접 액세스할 수 있습니다. 그러나 Python의 관례에 따르면 비공개로 간주되어야 하며 외부에서 사용해서는 안 됩니다. (꼭 사용해야 한다면 외부에서 사용하지 않는 것이 좋은 프로그래밍 방법입니다.) 동시에 Python 문서에 따르면 _object 및 __object의 범위는 이 모듈로 제한됩니다.

========================================== == ==================================
파이썬 명명 메커니즘을 이해합니다(단일 및 이중으로 시작). 밑줄) (재인쇄: http://blog.csdn.net/lanphaday)
소개
다음 프로그램의 출력을 추측해 보시기 바랍니다.
클래스 A(객체):
def __init__(self):
self.__private()
self.public()
def __private(self):
print 'A.__private()'
def public(self):
print 'A.public()'
class B(A):
def __private(self):
print 'B.__private()'
def public(self):
print 'B.public()'
b = B()
First Look
정답은 다음과 같습니다:
A.__private()
B.public()
이미 추측이 옳았다면 제 블로그 게시물을 읽을 필요가 없습니다. 추측이 정확하지 않거나 궁금한 점이 있으시면 제 블로그 게시물이 바로 여러분을 위한 것입니다.
모든 것은 "A.__private()"이 출력되는 이유에서 시작됩니다. 하지만 그 이유를 설명하려면 Python의 명명 메커니즘을 이해해야 합니다.
Python 매뉴얼에 따르면 변수 이름(식별자)은 Python의 원자 요소입니다. 변수명이 객체에 묶일 때, 변수명은 인간사회에서와 마찬가지로 객체를 지칭하는 것이겠죠? 변수 이름이 코드 블록에 나타나면 지역 변수이고, 변수 이름이 모듈에 나타나면 전역 변수입니다. 모두가 모듈에 대해 잘 이해하고 있다고 생각하지만, 코드 블록이 약간 혼란스러울 수 있습니다. 여기에 설명하세요:
코드 블록은 실행 가능 단위로 사용할 수 있는 Python 프로그램 텍스트의 일부입니다. 모듈, 함수 본문 및 클래스 정의는 모두 코드 블록입니다. 뿐만 아니라 모든 대화형 스크립트 명령도 코드 블록입니다. 스크립트 파일도 코드 블록이고 명령줄 스크립트도 코드 블록입니다.
다음으로 변수의 가시성에 대해 이야기해 보겠습니다. 범위는 코드 블록 내 변수 이름의 가시성입니다. 지역 변수가 코드 블록에 정의된 경우 범위에는 이 코드 블록이 포함됩니다. 변수가 함수 코드 블록에 정의된 경우 동일한 이름의 다른 변수가 정의되지 않는 한 범위는 함수 블록의 모든 코드 블록으로 확장됩니다. 그러나 클래스에 정의된 변수의 범위는 클래스 코드 블록으로 제한되며 메서드 코드 블록으로 확장되지 않습니다.
민종
이전 섹션의 이론에 따르면 코드를 클래스 A 정의, 클래스 B 정의, 변수 b 정의의 세 가지 코드 블록으로 나눌 수 있습니다. 클래스 정의에 따르면, 코드가 클래스 A에 대해 세 개의 멤버 변수를 정의한다는 것을 알고 있습니다(Python의 함수도 객체이므로 멤버 메서드를 멤버 변수라고 하면 작동합니다.) 클래스 B는 두 개의 멤버 변수를 정의합니다. 이는 다음 코드로 확인할 수 있습니다:
>>> print 'n'.join(dir(A))
_A__private
__init__
public
>>> ; print 'n'.join(dir(B))
_A__private
_B__private
__init__
public
왜 클래스 A에 _A__private이라는 속성이 있나요? 그리고 __private이 사라졌습니다! 이것은 Python의 개인 변수 억제에 대해 이야기하는 것입니다.
탐색
Python을 아는 친구들은 Python이 두 개 이상의 밑줄 문자로 시작하고 두 개 이상의 밑줄 문자로 끝나지 않는 변수를 개인 변수로 처리한다는 것을 알고 있습니다. 개인 변수는 코드 생성 전에 긴 형식(공개)으로 변환됩니다. 변환 메커니즘은 다음과 같습니다. 변수 앞에 클래스 이름을 삽입한 다음 앞에 밑줄 문자를 추가합니다. 이를 개인 이름 맹글링이라고 합니다. 예를 들어 클래스 A의 __private 식별자는 _A__private으로 변환됩니다. 이것이 바로 이전 섹션에서 _A__private 및 __private가 사라진 이유입니다.
두 가지 여담:
첫째, 롤링하면 식별자가 길어지기 때문에 255를 초과하면 Python에서 이로 인해 발생하는 이름 충돌에 주의하세요.
둘째, 클래스 이름이 모두 밑줄로 지정되면 Python은 더 이상 압축을 수행하지 않습니다. 예:
>>> class ____(object):
def __init__(self):
self.__method()
def __method(self):
print ' ____ .__method()'
>>> print 'n'.join(dir(____))
__class__
__delattr__
__dict__
__doc__
__getattribute__
__hash__
__init__
__method                                                    ​>__weakref__
>> ;> method()
>>> obj.__method() # 가능 외부에서 호출됨
____.__method()
이제 다시 돌아가서 "A.__private()"이 출력되는 이유를 살펴보겠습니다!
진실
똑똑한 독자님들은 이제 답을 짐작하셨을 거라 믿습니다. 아직 생각해보지 않으셨다면 힌트를 하나 드리겠습니다. 사실은 C 언어의 매크로 전처리와 유사합니다.
클래스 A는 전용 멤버 함수(변수)를 정의하기 때문에 코드 생성 전에 전용 변수 압착이 수행됩니다(이전 섹션에서 빨간색으로 표시된 줄을 보셨나요?). 롤링 후 클래스 A의 코드는 다음과 같습니다.
클래스 A(객체):
def __init__(self):
self._A__private() # 이 줄이 변경되었습니다
self.public()
def _A__private(self): # 이 줄도 변경되었습니다
                             print 'A.__private ()'
def public(self):
print 'A.public()'
약간 C 언어의 매크로 확장과 비슷하지 않나요?
클래스 B를 정의할 때 __init__ 메소드가 오버라이드되지 않았기 때문에 여전히 A.__init__이 호출되는 즉, self._A__private()이 실행되어 "A.__private()"이 자연스럽게 출력됩니다.
다음 두 코드는 설득력을 높이고 이해도를 높일 수 있습니다.
>>> class C(A):
def __init__(self): # __init__을 다시 작성하고 더 이상 self를 호출하지 않습니다._A__private
self.__private() # 여기에 바인딩된 것은 _C_private
self.public()
def __private(self):
print 'C.__private()'
def public( self):
print 'C.public()'
>>> c = C()
C.__private()
C.public()
# ## ####################
>>> 클래스 A(객체):
def __init__(self) : Self._a__private () # 정의되지 않은 함수를 호출하면 Python에서
Self.public ()
DEF __private (SELF):
Print 'A.__ Private ( )'
def public(self):
print 'A.public()'
>>>a = A()
A.__private()
A.public()

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.