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.
결론.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.