Python 의 단일,이중 밑줄 의 차이 점 요약

머리말
Python 의 코드 스타일 은 PEP 8 에서 설명 합 니 다.이 문 서 는 Python 프로 그래 밍 스타일 의 모든 면 을 묘사 하 였 다.이 문 서 를 지 키 는 조건 에서 서로 다른 프로그래머 가 작성 한 Python 코드 는 최대한 비슷 한 스타일 을 유지 할 수 있 습 니 다.이렇게 하면 읽 기 쉽 고 프로그래머 간 에 교류 하기 쉽다.
우리 모두 가 Python 을 공부 할 때 많은 사람들 이 왜 방법(method)앞 에 밑줄 을 여러 개 넣 는 지 이해 하지 못 하 는 것 같 습 니 다.때로는 양쪽 까지 넣 습 니 다.예 를 들 어this__이런제 가 위의 글 을 보기 전에 저 는 Python 에서 이러한 밑줄 의 역할 이 Golang 에서 방법/함수 의 대소 문자 와 같 거나 다른 언어 에서 private,Public 의 역할 과 같다 고 생각 했 습 니 다.그러나 자세히 따 져 보면 이것 은 모두 Python 처럼 디자인 한 취지 가 아 닙 니 다.
다음은 구체 적 으로 분석 해서 더 이상 할 말 이 없 으 니 한번 봅 시다.
밑줄 로 시작 하 다
우 리 는 방법 이나 속성 앞 에 단일 밑줄 을 그 은 것 을 자주 보고 이 방법 이나 속성 이 이 유형(Python 은 Golang 과 마찬가지 로 클래스 뿐만 아니 라 방법 도 있 을 수 있 고 여러 유형,심지어 기본 유형 도 방법 을 정의 할 수 있다)을 나타 내 는 개인 적 인 방법 이나 속성 이 라 고 생각한다.그러나 사실 Python 에는 진정한 의미 의 사유 방법 이나 속성 이 존재 하지 않 습 니 다.앞 에 밑줄 을 긋 습 니 다API 의 일부분 이 아니 기 때문에 이 방법 이나 속성 에 접근 해 서 는 안 된다 는 뜻 일 뿐이다.
예 를 들 어:

Python
class BaseForm(StrAndUnicode):
 ...

 def _get_errors(self):
 "Returns an ErrorDict for the data provided for the form"
 if self._errors is None:
 self.full_clean()
 return self._errors

 errors = property(_get_errors)
이 코드 세 션 은 Django 소스 코드(django/forms/forms.py)에서 왔 습 니 다.이 코드 의 디자인 은 errors 속성 이 대외 API 의 일부분 입 니 다.잘못된 정 보 를 얻 으 려 면 errors 속성 에 접근 해 야 합 니 다.get_errors 방법.
두 밑줄 로 시작 하 다
이전에 많은 사람들 이 나 에 게 파 이 썬 에서 두 밑줄 을 긋 는 것 은 처음에 사 유 를 나타 낸다 고 말 했 는데,나 는 많은 곳 에서 도 이런 견 해 를 보 았 다.이렇게 이해 하 는 것 도 틀 릴 수 없 지만 이것 은 Python 디자인 의 더 블 밑줄 로 시작 하 는 취지 와 목적 이 아 닙 니 다.Python 디자인 의 진정한 목적 은 하위 클래스 가 부 류 를 덮어 쓰 는 방법 을 피하 기 위 한 것 입 니 다.
우 리 는 예 를 보 자.

class A(object):
 
 def __method(self):
 print("I'm a method in class A")

 def method_x(self):
 print("I'm another method in class A
") def method(self): self.__method() self.method_x() class B(A): def __method(self): print("I'm a method in class B") def method_x(self): print("I'm another method in class B
") if __name__ == '__main__': print("situation 1:") a = A() a.method() b = B() b.method() print("situation 2:") # a.__method() a._A__method()
실행 결과:

situation 1:
I'm a method in class A
I'm another method in class A

I'm a method in class A
I'm another method in class B

situation 2:
I'm a method in class A
여기에 두 가지 주의해 야 할 점 이 있다.
A 류 에서 우 리 는method()、method_x 와 method()세 가지 방법;그리고 우 리 는 클래스 B 를 다시 정의 하여 A 에서 계승 하고 B 클래스 에 부모 클래스 의 를 덮어 씁 니 다.method()와 methodx 방법,그러나 출력 결 과 를 보면 B 대상 이 method()방법 을 호출 할 때 부모 클래스 A 의 를 호출 합 니 다.method()방법 과 자신의 methodx()방법.즉,method()복사 가 유효 하지 않 고 methodx()복사 가 효력 이 발생 했다.이것 이 바로 Python 이 더 블 밑줄 로 시작 하 는 유일한 목적 이다.
이 점 은 Python 공식 설명 에서 도 답 을 얻 을 수 있다.https://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables
앞에서 말 했 듯 이 Python 에는 진정한 의미 의 개인 변수 가 존재 하지 않 습 니 다.두 밑줄 로 시작 하 는 방법 과 속성 에 대해 서 는 직접 인용 할 수 없 지만,그것 은 Python 이 기본적으로 그 앞 에 접 두 사 를 붙 였 기 때 문 입 니 다클래스 이름,그래서 situation 2 아래 코드 처럼 a 로 직접 접근 할 수 는 없 지만method(),하지만 접 두 사 를 붙 여 접근 할 수 있 습 니 다.즉A__method()。
시작 과 끝 에 두 밑줄 을 긋다
일반적으로this__이런 시작 과 끝 에 두 밑줄 을 그 는 방법 은 이것 이 Python 이 스스로 호출 한 것 이 므 로 호출 하지 마 세 요.예 를 들 어 우 리 는 len()함 수 를 호출 하여 길 이 를 구 할 수 있 는데 사실은 배경 이len__()방법일반적으로 우 리 는 렌 을 사용 해 야 지 직접 사용 하 는 것 이 아니다len__():

a = [1, 2, 3]
print(len(a)) 
print(a.__len__()) #      

num = 10
print(num + 10)
print(num.__add__(10)) #      
우 리 는 일반적으로 라 고 부른다.len__()이런 방법 은 magic methods 이 고 일부 조작 부호 의 배경 에서 호출 하 는 것 도 이러한 magic methods 입 니 다.예 를 들 어+배경 에서 호출 하 는 것 은 입 니 다.add__,-호출 된 것 은sub__,그래서 이런 메커니즘 은 우리 로 하여 금 자신의 클래스 에 조작 부 호 를 덮어 쓸 수 있 게 한다(뒤의 예 참조).또한 가끔 은 이런 시작 과 끝 에 두 밑줄 을 그 는 방법 은 특정한 장면 의 반전 함수 일 뿐 입 니 다.예 를 들 어init__()대상 초기 화 시 호출,new__()인 스 턴 스 를 구축 할 때 호출 됩 니 다.다음은 두 가지 예 를 보 겠 습 니 다.

class CrazyNumber(object):
 def __init__(self, n): 
 self.n = n 
 def __add__(self, other): 
 return self.n - other 
 def __sub__(self, other): 
 return self.n + other 
 def __str__(self): 
 return str(self.n) 

num = CrazyNumber(10) 
print(num) # output is: 10
print(num + 5) # output is: 5
print(num - 20) # output is: 30
위의 이 예 에서 우 리 는+와-조작 부 호 를 덮어 써 서 그들의 기능 을 교환 했다.다시 예 를 들 면:

class Room(object):
 def __init__(self): 
 self.people = [] 
 def add(self, person): 
 self.people.append(person) 
 def __len__(self): 
 return len(self.people)
 
room = Room() 
room.add("Igor") 
print len(room) # output is: 1
이 예 에서 우 리 는 를 실 현 했 기 때문이다.len__(),그래서 Room 대상 도 len 함 수 를 사용 할 수 있 습 니 다.
모든 이런 방법 은 여기에 설명 되 어 있다.documentation.
결론.
  • 단일 밑줄 사용(one_underline)시작 표시 방법 은 API 의 일부분 이 아니 므 로 직접 접근 하지 마 십시오.(문법 적 으로 도 문제 가 없 지만)4567918)
  • 더 블 밑줄 로 시작(two_underlines)시작 부분 은 하위 클래스 가 이 방법 을 덮어 쓸 수 없다 는 것 을 나타 낸다.네가 정말 네가 무엇 을 하고 있 는 지 알 지 않 으 면 이런 방식 을 사용 하지 마라.4567918)
  • 자신 이 정의 한 대상 도 Python 내 장 된 대상 처럼 Python 내 장 된 함수 나 연산 자(예 를 들 어 len,add,+,-,=등)를 사용 할 수 있 도록 하려 면 이러한 방법 을 정의 할 수 있 습 니 다.
  • 물론 일부 속성 은 끝 에 만 추가 되 지만 밑줄 을 긋 는 다.이것 은 우리 가 지은 이름과 Python 이 키워드 충돌 을 유지 하 는 것 을 피하 기 위해 서 일 뿐 특별한 의미 가 없다.
  • 주의:본 고의 대부분 내용 은Difference between _,and __xx in Python을 참고 한다.
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기