3.1. Objects, values and types
객체는 데이터에 대한 Python의 추상화입니다. Python 프로그램의 모든 데이터는 객체 또는 객체 간의 관계로 표현됩니다. (어떤 의미에서 Von Neumann의 “저장 프로그램 컴퓨터” 모델에 따라 코드도 객체로 표현됩니다.)
모든 개체에는 ID, 유형 및 값이 있습니다. 개체의 ID는 일단 생성되면 절대 변경되지 않습니다. 메모리에 있는 개체의 주소로 생각할 수 있습니다. ‘is’ 연산자는 두 개체의 ID를 비교합니다. id() 함수는 ID를 나타내는 정수를 반환합니다.
CPython 구현 세부 정보: CPython의 경우 id(x)는 x가 저장된 메모리 주소입니다.
개체의 유형은 개체가 지원하는 작업(예: “길이가 있습니까?”)을 결정하고 해당 유형의 개체에 가능한 값을 정의합니다. type() 함수는 객체의 유형(객체 자체)을 반환합니다. ID와 마찬가지로 객체의 유형도 변경할 수 없습니다.
일부 개체의 값은 변경될 수 있습니다. 값이 변경될 수 있는 객체는 변경 가능하다고 합니다. 일단 생성되면 값을 변경할 수 없는 객체를 불변(immutable)이라고 합니다. (가변 객체에 대한 참조를 포함하는 불변 컨테이너 객체의 값은 후자의 값이 변경될 때 변경될 수 있습니다. 그러나 컨테이너는 컨테이너에 포함된 객체 컬렉션을 변경할 수 없기 때문에 여전히 불변으로 간주됩니다. 변경할 수 없는 값을 갖는 것과 같으며 더 미묘합니다.) 개체의 변경 가능성은 해당 유형에 따라 결정됩니다. 예를 들어 숫자, 문자열 및 튜플은 변경할 수 없지만 사전 및 목록은 변경할 수 있습니다.
개체는 명시적으로 소멸되지 않습니다. 그러나 도달할 수 없게 되면 가비지 수집될 수 있습니다. 구현은 가비지 수집을 연기하거나 완전히 생략할 수 있습니다. 아직 도달 가능한 개체가 수집되지 않는 한 가비지 수집이 구현되는 방식은 구현 품질의 문제입니다.
CPython 구현 세부 정보: CPython은 현재 순환적으로 연결된 가비지의 지연 감지(선택 사항)와 함께 참조 계산 방식을 사용합니다. 이 방식은 대부분의 객체가 도달할 수 없게 되는 즉시 수집하지만 순환 참조를 포함하는 가비지 수집을 보장하지는 않습니다. 순환 가비지 수집 제어에 대한 정보는 gc 모듈의 문서를 참조하십시오. 다른 구현은 다르게 작동하며 CPython은 변경될 수 있습니다. 개체에 도달할 수 없게 되면 개체의 즉각적인 종료에 의존하지 마십시오(따라서 항상 파일을 명시적으로 닫아야 함).
구현의 추적 또는 디버깅 기능을 사용하면 일반적으로 수집 가능한 개체를 활성 상태로 유지할 수 있습니다. 또한 ‘try…except’ 문으로 예외를 포착하면 개체를 활성 상태로 유지할 수 있습니다.
일부 개체에는 열려 있는 파일이나 창과 같은 “외부” 리소스에 대한 참조가 포함되어 있습니다. 객체가 가비지 수집될 때 이러한 리소스가 해제되는 것으로 이해되지만 가비지 수집이 발생한다고 보장할 수 없기 때문에 이러한 객체는 일반적으로 close() 메서드와 같은 외부 리소스를 해제하는 명시적인 방법도 제공합니다. 이러한 개체를 명시적으로 닫는 프로그램을 사용하는 것이 좋습니다. ‘try…finally’ 문과 ‘with’ 문은 이를 수행하는 편리한 방법을 제공합니다.
일부 객체는 다른 객체에 대한 참조를 포함합니다. 이를 컨테이너라고 합니다. 컨테이너의 예로는 튜플, 목록 및 사전이 있습니다. 참조는 컨테이너 값의 일부입니다. 대부분의 경우 컨테이너의 값에 대해 이야기할 때 포함된 개체의 ID가 아니라 값을 의미합니다. 그러나 컨테이너의 변경 가능성에 대해 이야기할 때는 직접 포함된 개체의 ID만 암시됩니다. 따라서 불변 컨테이너(예: 튜플)에 가변 객체에 대한 참조가 포함된 경우 해당 가변 객체가 변경되면 해당 값이 변경됩니다.
유형은 객체 동작의 거의 모든 측면에 영향을 미칩니다. 개체 ID의 중요성도 어떤 의미에서는 영향을 받습니다. 변경 불가능한 유형의 경우 새 값을 계산하는 작업은 실제로 동일한 유형과 값을 가진 기존 개체에 대한 참조를 반환할 수 있지만 변경 가능한 개체의 경우에는 이것이 허용되지 않습니다. 예를 들어, a = 1 이후; b = 1, a와 b는 구현에 따라 값이 1인 동일한 객체를 참조하거나 참조하지 않을 수 있지만 c = [] 이후; d = [], c 및 d는 새로 생성된 두 개의 서로 다른 고유한 빈 목록을 참조하도록 보장됩니다. (c = d = []는 c와 d 모두에 동일한 개체를 할당합니다.)
3.2. The standard type hierarchy
다음은 Python에 내장된 유형의 목록입니다. 확장 모듈(구현에 따라 C, Java 또는 기타 언어로 작성됨)은 추가 유형을 정의할 수 있습니다. 미래 버전의 Python은 유형 계층에 유형을 추가할 수 있습니다(예: 유리수, 효율적으로 저장된 정수 배열 등). 이러한 추가는 종종 대신 표준 라이브러리를 통해 제공됩니다.
아래 유형 설명 중 일부에는 ‘특수 속성’을 나열하는 단락이 포함되어 있습니다. 이러한 속성은 구현에 대한 액세스를 제공하며 일반적인 용도로 사용되지 않습니다. 그들의 정의는 미래에 바뀔 수 있습니다.
None
이 유형에는 단일 값이 있습니다. 이 값을 가진 단일 개체가 있습니다. 이 객체는 기본 제공 이름 None을 통해 액세스됩니다. 많은 상황에서 값이 없음을 나타내는 데 사용됩니다. 예를 들어 명시적으로 아무 것도 반환하지 않는 함수에서 반환됩니다. 진리값은 거짓입니다.
NotImplemented
이 유형에는 단일 값이 있습니다. 이 값을 가진 단일 개체가 있습니다. 이 개체는 기본 제공 이름 NotImplemented를 통해 액세스됩니다. 숫자 메서드 및 풍부한 비교 메서드는 제공된 피연산자에 대한 연산을 구현하지 않는 경우 이 값을 반환해야 합니다. (그런 다음 인터프리터는 연산자에 따라 반영된 작업 또는 다른 폴백을 시도합니다.) 부울 컨텍스트에서 평가하면 안 됩니다.
자세한 내용은 산술 연산 구현을 참조하세요.
버전 3.9에서 변경: 부울 컨텍스트에서 NotImplemented를 평가하는 것은 더 이상 사용되지 않습니다. 현재 true로 평가되는 동안 DeprecationWarning을 내보냅니다. 미래 버전의 Python에서는 TypeError가 발생합니다.
Ellipsis
이 유형에는 단일 값이 있습니다. 이 값을 가진 단일 개체가 있습니다. 이 개체는 리터럴 …
또는 기본 제공 이름 Ellipsis를 통해 액세스됩니다. 그것의 진리값은 참입니다.
numbers.Number
이들은 숫자 리터럴에 의해 생성되고 산술 연산자 및 산술 내장 함수에 의해 결과로 반환됩니다. 숫자 개체는 변경할 수 없습니다. 한번 생성되면 그 가치는 절대 변하지 않습니다. 파이썬 숫자는 물론 수학 숫자와 밀접한 관련이 있지만 컴퓨터의 숫자 표현에는 한계가 있습니다.
repr() 및 str()에 의해 계산되는 숫자 클래스의 문자열 표현에는 다음과 같은 속성이 있습니다.
- 이들은 클래스 생성자에 전달될 때 원래 숫자 값을 갖는 객체를 생성하는 유효한 숫자 리터럴입니다.
- 가능한 경우 10진법으로 표현됩니다.
- 소수점 앞의 단일 0을 제외한 선행 0은 표시되지 않습니다.
- 소수점 뒤의 단일 0을 제외한 후행 0은 표시되지 않습니다.
- 숫자가 음수일 때만 부호가 표시됩니다.
Python은 정수, 부동 소수점 숫자 및 복소수를 구별합니다.
numbers.Integral
이들은 수학적 정수 집합(양수 및 음수)의 요소를 나타냅니다.
정수에는 두 가지 유형이 있습니다.
Integers (int)
이들은 사용 가능한 (가상) 메모리에만 적용되는 무제한 범위의 숫자를 나타냅니다. 시프트 및 마스크 연산의 목적을 위해 이진 표현이 가정되고 음수는 2의 보수 변형으로 표현되어 왼쪽으로 확장되는 무한 부호 비트 문자열의 환상을 제공합니다.
Booleans (bool)
이것들은 참값 False와 True를 나타냅니다. False 및 True 값을 나타내는 두 개체는 유일한 부울 개체입니다. 부울 유형은 정수 유형의 하위 유형이며 부울 값은 거의 모든 컨텍스트에서 각각 값 0과 1처럼 작동합니다. 예외는 문자열로 변환할 때 문자열 “False” 또는 “True”가 반환된다는 것입니다. , 각각.
정수 표현에 대한 규칙은 음의 정수와 관련된 시프트 및 마스크 연산을 가장 의미 있게 해석하기 위한 것입니다.
numbers.Real (float)
이들은 기계 수준 배정도 부동 소수점 숫자를 나타냅니다. 허용되는 범위와 오버플로 처리를 위해 기본 기계 아키텍처(및 C 또는 Java 구현)에 따라 결정됩니다. Python은 단정밀도 부동 소수점 숫자를 지원하지 않습니다. 일반적으로 이를 사용하는 이유인 프로세서 및 메모리 사용량 절감은 Python에서 개체를 사용하는 오버헤드로 인해 왜소해지기 때문에 두 종류의 부동 소수점 숫자로 언어를 복잡하게 만들 이유가 없습니다.
numbers.Complex (complex)
이것들은 복소수를 기계 수준 배정밀도 부동 소수점 숫자 쌍으로 나타냅니다. 부동 소수점 숫자와 동일한 주의 사항이 적용됩니다. 복소수 z
의 실수부와 허수부는 읽기 전용 속성 z.real
및 z.imag
를 통해 검색할 수 있습니다.
Sequences
이들은 음수가 아닌 숫자로 인덱싱된 유한 순서 집합을 나타냅니다. 내장 함수 len()은 시퀀스의 항목 수를 반환합니다. 시퀀스의 길이가 n인 경우 인덱스 집합에는 숫자 0, 1, …, n-1이 포함됩니다. 시퀀스 a의 항목 i는 a[i]에 의해 선택됩니다.
시퀀스는 슬라이싱도 지원합니다. a[i:j]는 i <= k < j인 인덱스 k를 가진 모든 항목을 선택합니다. 표현식으로 사용될 때 슬라이스는 동일한 유형의 시퀀스입니다. 이는 인덱스 세트가 0부터 시작하도록 번호가 다시 지정됨을 의미합니다.
일부 시퀀스는 세 번째 “단계” 매개 변수를 사용하여 “확장된 슬라이싱”도 지원합니다. a[i:j:k]는 인덱스 x가 있는 a의 모든 항목을 선택합니다. 여기서 x = i + n*k, n >= 0 및 i <= x입니다. < j.
시퀀스는 가변성에 따라 구분됩니다.
Immutable sequences
불변 시퀀스 유형의 객체는 일단 생성되면 변경할 수 없습니다. (객체가 다른 객체에 대한 참조를 포함하는 경우 이러한 다른 객체는 변경 가능하고 변경될 수 있습니다. 그러나 변경 불가능한 객체가 직접 참조하는 객체 컬렉션은 변경할 수 없습니다.)
다음 유형은 변경할 수 없는 시퀀스입니다.
Strings
문자열은 유니코드 코드 포인트를 나타내는 일련의 값입니다. U+0000 – U+10FFFF 범위의 모든 코드 포인트는 문자열로 나타낼 수 있습니다. Python에는 char 유형이 없습니다. 대신 문자열의 모든 코드 포인트는 길이가 1인 문자열 객체로 표시됩니다. 내장 함수 ord()는 코드 포인트를 문자열 형식에서 0 – 10FFFF 범위의 정수로 변환합니다. chr()은 0 – 10FFFF 범위의 정수를 해당 길이 1 문자열 객체로 변환합니다. str.encode()는 주어진 텍스트 인코딩을 사용하여 str을 바이트로 변환하는 데 사용할 수 있으며 bytes.decode()는 그 반대를 달성하는 데 사용할 수 있습니다.
Tuples
튜플의 항목은 임의의 파이썬 객체입니다. 두 개 이상의 항목으로 구성된 튜플은 쉼표로 구분된 표현식 목록으로 구성됩니다. 한 항목의 튜플(‘싱글톤’)은 표현식에 쉼표를 추가하여 형성할 수 있습니다(표현식을 그룹화하는 데 괄호를 사용할 수 있어야 하므로 표현식 자체는 튜플을 생성하지 않습니다). 빈 튜플은 빈 괄호 쌍으로 구성될 수 있습니다.
Bytes
바이트 객체는 불변 배열입니다. 항목은 0 <= x < 256 범위의 정수로 표현되는 8비트 바이트입니다. b’abc’와 같은 바이트 리터럴과 내장 bytes() 생성자를 사용하여 바이트 객체를 생성할 수 있습니다. 또한 바이트 객체는 decode() 메서드를 통해 문자열로 디코딩될 수 있습니다.
Mutable sequences
변경 가능한 시퀀스는 생성된 후 변경할 수 있습니다. 구독 및 슬라이싱 표기법은 할당 및 del(삭제) 문의 대상으로 사용할 수 있습니다.
현재 다음과 같은 두 가지 고유 변경 가능 시퀀스 유형이 있습니다.
Lists
목록의 항목은 임의의 Python 객체입니다. 목록은 쉼표로 구분된 식 목록을 대괄호 안에 넣어 구성됩니다. (길이가 0 또는 1인 목록을 구성하는 데 필요한 특별한 경우가 없음에 유의하십시오.)
Byte Arrays
bytearray 객체는 변경 가능한 배열입니다. 내장 bytearray() 생성자에 의해 생성됩니다. 변경 가능(따라서 해시 불가능)한 것 외에도 바이트 배열은 변경 불가능한 바이트 객체와 동일한 인터페이스 및 기능을 제공합니다.
확장 모듈 배열은 collections 모듈과 마찬가지로 변경 가능한 시퀀스 유형의 추가 예를 제공합니다.
Set types
이들은 고유하고 변경 불가능한 객체의 정렬되지 않은 유한 집합을 나타냅니다. 따라서 아래 첨자로 인덱싱할 수 없습니다. 그러나 반복될 수 있으며 내장 함수 len()은 집합의 항목 수를 반환합니다. 세트의 일반적인 용도는 빠른 멤버십 테스트, 시퀀스에서 중복 제거, 교집합, 합집합, 차이 및 대칭 차이와 같은 수학적 연산 계산입니다.
집합 요소의 경우 사전 키와 동일한 불변성 규칙이 적용됩니다. 숫자 유형은 숫자 비교에 대한 일반적인 규칙을 따릅니다. 두 숫자가 같다고 비교되면(예: 1과 1.0) 둘 중 하나만 집합에 포함될 수 있습니다.
현재 두 가지 고유 세트 유형이 있습니다.
Sets
이들은 변경 가능한 집합을 나타냅니다. 이들은 내장 set() 생성자에 의해 생성되며 나중에 add()와 같은 여러 메서드로 수정할 수 있습니다.
Frozen sets
이들은 불변 세트를 나타냅니다. 이들은 내장 frozenset() 생성자에 의해 생성됩니다. frozenset은 변경 불가능하고 해시 가능하므로 다른 집합의 요소로 다시 사용하거나 사전 키로 사용할 수 있습니다.
Mappings
이들은 임의의 인덱스 세트로 인덱싱된 유한 객체 세트를 나타냅니다. 아래 첨자 표기법 a[k]는 매핑 a에서 k로 인덱싱된 항목을 선택합니다. 이것은 식에서 할당 또는 del 문의 대상으로 사용할 수 있습니다. 내장 함수 len()은 매핑의 항목 수를 반환합니다.
현재 단일 고유 매핑 유형이 있습니다.
Dictionaries
이들은 거의 임의의 값으로 인덱싱된 유한 개체 집합을 나타냅니다. 키로 허용되지 않는 유일한 유형의 값은 목록이나 사전 또는 객체 ID가 아닌 값으로 비교되는 기타 변경 가능한 유형을 포함하는 값입니다. 그 이유는 사전을 효율적으로 구현하려면 키의 해시 값이 일정하게 유지되어야 하기 때문입니다. 키에 사용되는 숫자 유형은 숫자 비교에 대한 일반 규칙을 따릅니다. 두 숫자가 같다고 비교되면(예: 1과 1.0) 동일한 사전 항목을 색인화하는 데 서로 교환하여 사용할 수 있습니다.
사전은 삽입 순서를 유지합니다. 즉, 사전에 순차적으로 추가된 순서대로 키가 생성됩니다. 기존 키를 교체해도 순서는 변경되지 않지만 키를 제거하고 다시 삽입하면 이전 위치를 유지하는 대신 끝에 추가됩니다.
사전은 변경 가능합니다. {…} 표기법으로 만들 수 있습니다(사전 표시 섹션 참조).
확장 모듈 dbm.ndbm 및 dbm.gnu는 컬렉션 모듈과 마찬가지로 매핑 유형의 추가 예를 제공합니다.
버전 3.7에서 변경: 사전은 Python 3.6 이전 버전에서 삽입 순서를 유지하지 않았습니다. CPython 3.6에서는 삽입 순서가 유지되었지만 당시에는 언어 보장이 아니라 구현 세부 사항으로 간주되었습니다.
Callable types
다음은 함수 호출 작업(호출 섹션 참조)이 적용될 수 있는 유형입니다.
User-defined functions
사용자 정의 함수 개체는 함수 정의에 의해 생성됩니다(함수 정의 섹션 참조). 함수의 형식 매개변수 목록과 동일한 수의 항목을 포함하는 인수 목록으로 호출해야 합니다.
Special attributes:
Attribute | Meaning | |
---|
__doc__ | 함수의 문서 문자열 또는 사용할 수 없는 경우 None; 하위 클래스에 의해 상속되지 않습니다. | Writable |
__name__ | 함수의 이름입니다. | Writable |
__qualname__ | 함수의 정규화된 이름입니다. 버전 3.3의 새로운 기능. | Writable |
__module__ | 함수가 정의된 모듈의 이름 또는 사용할 수 없는 경우 None. | Writable |
__defaults__ | 기본값이 있는 인수에 대한 기본 인수 값을 포함하는 튜플 또는 기본값이 있는 인수가 없으면 None입니다. | Writable |
__code__ | 컴파일된 함수 본문을 나타내는 코드 개체입니다. | Writable |
__globals__ | 함수의 전역 변수를 포함하는 사전에 대한 참조 — 함수가 정의된 모듈의 전역 네임스페이스. | Read-only |
__dict__ | 임의의 함수 속성을 지원하는 네임스페이스. | Writable |
__closure__ | 없음 또는 함수의 자유 변수에 대한 바인딩을 포함하는 셀 튜플. cell_contents 속성에 대한 정보는 아래를 참조하십시오. | Read-only |
__annotations__ | 매개변수의 주석을 포함하는 dict입니다. dict의 키는 매개변수 이름과 반환 주석(제공된 경우)의 ‘return’입니다. 이 속성 작업에 대한 자세한 내용은 주석 모범 사례를 참조하십시오. | Writable |
__kwdefaults__ | 키워드 전용 매개변수의 기본값을 포함하는 사전입니다. | Writable |
“Writable”로 표시된 대부분의 속성은 할당된 값의 유형을 확인합니다.
함수 객체는 예를 들어 메타데이터를 함수에 첨부하는 데 사용할 수 있는 임의의 속성 가져오기 및 설정도 지원합니다. 일반 속성 점 표기법은 이러한 속성을 가져오고 설정하는 데 사용됩니다. 현재 구현은 사용자 정의 함수의 함수 속성만 지원합니다. 내장 함수의 함수 속성은 향후 지원될 수 있습니다.
셀 개체에는 cell_contents 속성이 있습니다. 셀 값을 가져오고 값을 설정하는 데 사용할 수 있습니다.
함수 정의에 대한 추가 정보는 해당 코드 개체에서 검색할 수 있습니다. 아래의 내부 유형에 대한 설명을 참조하십시오. 셀 유형은 types 모듈에서 액세스할 수 있습니다.
Instance methods
인스턴스 메서드 개체는 클래스, 클래스 인스턴스 및 호출 가능한 개체(일반적으로 사용자 정의 함수)를 결합합니다.
특수 읽기 전용 속성: __self__는 클래스 인스턴스 객체이고 __func__은 함수 객체입니다. __doc__은 메서드의 문서입니다(__func__.__doc__과 동일). __name__은 메서드 이름입니다(__func__.__name__과 동일). __module__은 메서드가 정의된 모듈의 이름이거나 사용할 수 없는 경우 None입니다.
메서드는 기본 함수 개체의 임의 함수 특성에 대한 액세스(설정은 아님)도 지원합니다.
해당 속성이 사용자 정의 함수 개체 또는 클래스 메서드 개체인 경우 클래스의 속성을 가져올 때(아마도 해당 클래스의 인스턴스를 통해) 사용자 정의 메서드 개체가 생성될 수 있습니다.
인스턴스 중 하나를 통해 클래스에서 사용자 정의 함수 개체를 검색하여 인스턴스 메서드 개체를 만들 때 해당 __self__ 특성이 인스턴스이고 메서드 개체가 바인딩되었다고 합니다. 새 메소드의 __func__ 속성은 원래 함수 객체입니다.
클래스 또는 인스턴스에서 클래스 메서드 객체를 검색하여 인스턴스 메서드 객체를 만들 때 __self__ 속성은 클래스 자체이고 __func__ 속성은 클래스 메서드의 기반이 되는 함수 객체입니다.
인스턴스 메소드 객체가 호출되면 기본 함수(__func__)가 호출되어 인수 목록 앞에 클래스 인스턴스(__self__)를 삽입합니다. 예를 들어, C가 함수 f()에 대한 정의를 포함하는 클래스이고 x가 C의 인스턴스일 때 x.f(1)을 호출하는 것은 C.f(x, 1)을 호출하는 것과 같습니다.
인스턴스 메서드 객체가 클래스 메서드 객체에서 파생되면 __self__에 저장된 “클래스 인스턴스”는 실제로 클래스 자체가 되므로 x.f(1) 또는 C.f(1)를 호출하는 것은 f(C,1)을 호출하는 것과 같습니다. ) 여기서 f는 기본 함수입니다.
함수 개체에서 인스턴스 메서드 개체로의 변환은 속성이 인스턴스에서 검색될 때마다 발생합니다. 경우에 따라 유익한 최적화는 특성을 지역 변수에 할당하고 해당 지역 변수를 호출하는 것입니다. 또한 이 변환은 사용자 정의 함수에 대해서만 발생합니다. 다른 호출 가능한 객체(및 모든 호출 불가능한 객체)는 변환 없이 검색됩니다. 클래스 인스턴스의 특성인 사용자 정의 함수는 바인딩된 메서드로 변환되지 않는다는 점도 중요합니다. 이것은 함수가 클래스의 속성일 때만 발생합니다.
Generator functions
yield 문을 사용하는 함수나 메서드(yield 문 참조)를 제너레이터 함수라고 합니다. 이러한 함수는 호출될 때 항상 함수 본문을 실행하는 데 사용할 수 있는 반복자 객체를 반환합니다. 반복자의 iterator.__next__() 메서드를 호출하면 yield 문을 사용하여 값을 제공할 때까지 함수가 실행됩니다. 함수가 return 문을 실행하거나 끝에서 떨어지면 StopIteration 예외가 발생하고 반복자는 반환할 값 집합의 끝에 도달합니다.
Coroutine functions
async def를 사용하여 정의된 함수 또는 메서드를 코루틴 함수라고 합니다. 이러한 함수는 호출될 때 코루틴 객체를 반환합니다. 여기에는 async with 및 async for 문뿐만 아니라 await 표현식이 포함될 수 있습니다. 코루틴 객체 섹션도 참조하십시오.
Asynchronous generator functions
async def를 사용하여 정의되고 yield 문을 사용하는 함수 또는 메서드를 비동기 생성기 함수라고 합니다. 이러한 함수는 호출될 때 함수 본문을 실행하기 위해 async for 문에서 사용할 수 있는 비동기 이터레이터 객체를 반환합니다.
비동기 이터레이터의 aiterator.__anext__ 메서드를 호출하면 awaitable이 반환될 것입니다. awaitable은 yield 표현식을 사용하여 값을 제공할 때까지 실행됩니다. 함수가 빈 반환 문을 실행하거나 끝에서 떨어지면 StopAsyncIteration 예외가 발생하고 비동기 반복자는 산출할 값 집합의 끝에 도달하게 됩니다.
Built-in functions
내장 함수 개체는 C 함수를 둘러싼 래퍼입니다. 내장 함수의 예는 len() 및 math.sin()입니다(math는 표준 내장 모듈입니다). 인수의 수와 유형은 C 함수에 의해 결정됩니다. 특수 읽기 전용 속성: __doc__은 함수의 문서 문자열이거나 사용할 수 없는 경우 None입니다. __name__은 함수의 이름입니다. __self__는 None으로 설정됩니다(하지만 다음 항목 참조). __module__은 함수가 정의된 모듈의 이름이거나 사용할 수 없는 경우 None입니다.
Built-in methods
이것은 실제로 내장 함수의 다른 변장이며, 이번에는 암시적 추가 인수로 C 함수에 전달된 개체를 포함합니다. 내장 메서드의 예는 alist가 목록 객체라고 가정할 때 alist.append()입니다. 이 경우 특수한 읽기 전용 속성 __self__는 alist로 표시된 객체로 설정됩니다.
Classes
클래스는 호출 가능합니다. 이러한 객체는 일반적으로 자신의 새 인스턴스에 대한 팩토리 역할을 하지만 __new__()를 재정의하는 클래스 유형에 대한 변형이 가능합니다. 호출의 인수는 __new__()에 전달되고, 일반적인 경우에는 __init__()에 전달되어 새 인스턴스를 초기화합니다.
Class Instances
임의 클래스의 인스턴스는 해당 클래스에 __call__() 메서드를 정의하여 호출 가능하게 만들 수 있습니다.
Modules
모듈은 Python 코드의 기본 구성 단위이며 import 문에 의해 호출되거나 importlib.import_module() 및 내장 __import()__
와 같은 함수를 호출하여 가져오기 시스템에 의해 생성됩니다. 모듈 객체에는 사전 객체(모듈에 정의된 함수의__globals__
속성이 참조하는 사전)에 의해 구현된 네임스페이스가 있습니다. 속성 참조는 이 사전의 조회로 변환됩니다. 예를 들어 m.x는 m.__dict__["x"]
와 같습니다. 모듈 객체는 모듈을 초기화하는 데 사용되는 코드 객체를 포함하지 않습니다(초기화가 완료되면 필요하지 않기 때문).
속성 할당은 모듈의 네임스페이스 사전을 업데이트합니다. 예를 들어 m.x = 1은 m.__dict__["x"] = 1
과 같습니다.
미리 정의된(쓰기 가능) 속성:
__name__
모듈의 이름입니다.
__doc__
모듈의 문서 문자열 또는 사용할 수 없는 경우 None입니다.
__file__
모듈이 파일에서 로드된 경우 모듈이 로드된 파일의 경로 이름입니다. __file__
속성은 인터프리터에 정적으로 연결된 C 모듈과 같은 특정 유형의 모듈에 대해 누락될 수 있습니다. 공유 라이브러리에서 동적으로 로드된 확장 모듈의 경우 공유 라이브러리 파일의 경로 이름입니다.
__annotations__
모듈 본문 실행 중에 수집된 변수 주석을 포함하는 사전입니다. __annotations__
작업에 대한 모범 사례는 Annotations Best Practices를 참조하십시오.
특수 읽기 전용 속성: __dict__
는 사전 객체로서의 모듈의 네임스페이스입니다.
CPython 구현 세부 사항: CPython이 모듈 사전을 지우는 방식으로 인해 사전에 여전히 활성 참조가 있더라도 모듈이 범위를 벗어나면 모듈 사전이 지워집니다. 이를 방지하려면 사전을 복사하거나 사전을 직접 사용하는 동안 모듈을 유지하십시오.
Custom classes
사용자 지정 클래스 유형은 일반적으로 클래스 정의에 의해 생성됩니다(클래스 정의 섹션 참조). 클래스에는 사전 개체에 의해 구현된 네임스페이스가 있습니다. 클래스 속성 참조는 이 사전에서 검색으로 변환됩니다. 예를 들어 C.x
는 C.__dict__["x"]
로 변환됩니다(속성을 찾는 다른 방법을 허용하는 많은 후크가 있지만). 속성 이름이 없으면 기본 클래스에서 속성 검색이 계속됩니다. 이 기본 클래스 검색은 공통 조상으로 돌아가는 여러 상속 경로가 있는 ‘다이아몬드’ 상속 구조가 있는 경우에도 올바르게 작동하는 C3 메서드 해결 순서를 사용합니다. Python에서 사용하는 C3 MRO에 대한 추가 세부 정보는 https://www.python.org/download/releases/2.3/mro/에서 2.3 릴리스와 함께 제공되는 설명서에서 찾을 수 있습니다.
클래스 속성 참조(예를 들어 클래스 C에 대한)가 클래스 메소드 객체를 산출할 때 __self __
속성이 C인 인스턴스 메소드 객체로 변환됩니다. 정적 메소드 객체를 산출할 때 다음으로 래핑된 객체로 변환됩니다. 정적 메소드 객체. 클래스에서 검색된 속성이 __dict__
에 실제로 포함된 속성과 다를 수 있는 또 다른 방법에 대해서는 설명자 구현 섹션을 참조하세요.
클래스 특성 할당은 기본 클래스의 사전이 아니라 클래스의 사전을 업데이트합니다.
클래스 객체를 호출(위 참조)하여 클래스 인스턴스(아래 참조)를 생성할 수 있습니다.
Special attributes:
__name__
클래스 이름입니다.
__module__
클래스가 정의된 모듈의 이름입니다.
__dict__
클래스의 네임스페이스를 포함하는 사전입니다.
__bases__
기본 클래스 목록에 나타나는 순서대로 기본 클래스를 포함하는 튜플입니다.
__doc__
클래스의 문서 문자열 또는 정의되지 않은 경우 None입니다.
__annotations__
클래스 본문 실행 중에 수집된 변수 주석을 포함하는 사전입니다. __annotations__
작업에 대한 모범 사례는 Annotations Best Practices를 참조하십시오.
Class instances
클래스 인스턴스는 클래스 개체를 호출하여 생성됩니다(위 참조). 클래스 인스턴스에는 속성 참조가 검색되는 첫 번째 위치인 사전으로 구현된 네임스페이스가 있습니다. 거기에서 속성을 찾을 수 없고 인스턴스의 클래스에 해당 이름의 속성이 있는 경우 클래스 속성으로 검색이 계속됩니다. 사용자 정의 함수 개체인 클래스 속성이 발견되면 __self__
속성이 인스턴스인 인스턴스 메서드 개체로 변환됩니다. 정적 메서드 및 클래스 메서드 개체도 변환됩니다. 위의 “클래스”를 참조하십시오. 인스턴스를 통해 검색된 클래스의 속성이 클래스의 __dict__
에 실제로 저장된 객체와 다를 수 있는 또 다른 방법에 대해서는 설명자 구현 섹션을 참조하세요. 클래스 속성이 발견되지 않고 객체의 클래스에 __getattr__()
메서드가 있으면 조회를 충족하기 위해 호출됩니다.
속성 할당 및 삭제는 클래스의 사전이 아닌 인스턴스의 사전을 업데이트합니다. 클래스에 __setattr__()
또는 __delattr__()
메서드가 있으면 인스턴스 사전을 직접 업데이트하는 대신 이 메서드가 호출됩니다.
클래스 인스턴스는 특정 특수 이름을 가진 메서드가 있는 경우 숫자, 시퀀스 또는 매핑인 것처럼 가장할 수 있습니다. 특수 메소드 이름 섹션을 참조하십시오.
Special attributes: __dict__
는 속성 사전입니다. __class__
는 인스턴스의 클래스입니다.
I/O objects (also known as file objects)
파일 객체는 열린 파일을 나타냅니다. open() 내장 함수, os.popen(), os.fdopen(), 소켓 객체의 makefile() 메서드(및 제공되는 다른 함수나 메서드)와 같은 다양한 단축키를 사용하여 파일 개체를 만들 수 있습니다. 확장 모듈에 의해).
sys.stdin, sys.stdout 및 sys.stderr 개체는 인터프리터의 표준 입력, 출력 및 오류 스트림에 해당하는 파일 개체로 초기화됩니다. 그들은 모두 텍스트 모드에서 열려 있으므로 io.TextIOBase 추상 클래스에 의해 정의된 인터페이스를 따릅니다.
Internal types
인터프리터가 내부적으로 사용하는 몇 가지 유형이 사용자에게 노출됩니다. 해당 정의는 향후 버전의 인터프리터에서 변경될 수 있지만 여기에서는 완전성을 위해 언급합니다.
Code objects
코드 개체는 바이트 컴파일된 실행 가능한 Python 코드 또는 바이트코드를 나타냅니다. 코드 개체와 함수 개체의 차이점은 함수 개체에는 함수의 전역(함수가 정의된 모듈)에 대한 명시적 참조가 포함되는 반면 코드 개체에는 컨텍스트가 없다는 점입니다. 또한 기본 인수 값은 코드 개체가 아닌 함수 개체에 저장됩니다(런타임에 계산된 값을 나타내기 때문). 함수 개체와 달리 코드 개체는 변경할 수 없으며 변경 가능한 개체에 대한 참조(직접 또는 간접적)를 포함하지 않습니다.
특수 읽기 전용 속성: co_name은 함수 이름을 제공합니다. co_qualname은 정규화된 함수 이름을 제공합니다. co_argcount는 위치 인수의 총 수입니다(위치 전용 인수 및 기본값이 있는 인수 포함). co_posonlyargcount는 위치 전용 인수(기본값이 있는 인수 포함)의 수입니다. co_kwonlyargcount는 키워드 전용 인수(기본값이 있는 인수 포함)의 수입니다. co_nlocals는 함수가 사용하는 지역 변수(인수 포함)의 수입니다. co_varnames는 지역 변수의 이름을 포함하는 튜플입니다(인수 이름으로 시작). co_cellvars는 중첩 함수가 참조하는 지역 변수의 이름을 포함하는 튜플입니다. co_freevars는 자유 변수의 이름을 포함하는 튜플입니다. co_code는 바이트코드 명령의 시퀀스를 나타내는 문자열입니다. co_consts는 바이트코드에서 사용하는 리터럴을 포함하는 튜플입니다. co_names는 바이트코드에서 사용하는 이름을 포함하는 튜플입니다. co_filename은 코드가 컴파일된 파일 이름입니다. co_firstlineno는 함수의 첫 번째 줄 번호입니다. co_lnotab은 바이트코드 오프셋에서 줄 번호로의 매핑을 인코딩하는 문자열입니다(자세한 내용은 인터프리터의 소스 코드 참조). co_stacksize는 필요한 스택 크기입니다. co_flags는 인터프리터에 대한 여러 플래그를 인코딩하는 정수입니다.
다음 플래그 비트는 co_flags에 대해 정의됩니다. 함수가 *arguments 구문을 사용하여 위치 인수의 임의 개수를 허용하는 경우 비트 0x04가 설정됩니다. 함수가 **키워드 구문을 사용하여 임의의 키워드 인수를 허용하는 경우 비트 0x08이 설정됩니다. 함수가 생성기이면 비트 0x20이 설정됩니다.
Future 기능 선언(from __future__ import division
)도 co_flags의 비트를 사용하여 특정 기능이 활성화된 상태로 코드 객체가 컴파일되었는지 여부를 나타냅니다. 비트 0x10 및 0x1000은 이전 버전의 Python에서 사용되었습니다.
co_flags의 다른 비트는 내부용으로 예약되어 있습니다.
코드 개체가 함수를 나타내는 경우 co_consts의 첫 번째 항목은 함수의 문서화 문자열이거나 정의되지 않은 경우 None입니다.
codeobject.co_positions()
코드 객체에서 각 바이트 코드 명령의 소스 코드 위치에 대한 반복 가능 항목을 반환합니다.
반복자는 (start_line, end_line, start_column, end_column)을 포함하는 튜플을 반환합니다. i번째 튜플은 i번째 명령으로 컴파일된 소스 코드의 위치에 해당합니다. 열 정보는 주어진 소스 라인에서 0-인덱스 utf-8 바이트 오프셋입니다.
이 위치 정보가 누락되었을 수 있습니다. 이러한 상황이 발생할 수 있는 일부 사례 목록:
- -X no_debug_ranges로 인터프리터를 실행합니다.
- -X no_debug_ranges를 사용하는 동안 컴파일된 pyc 파일을 로드합니다.
- 인공 명령에 해당하는 튜플을 배치합니다.
- 구현 특정 제한으로 인해 표시할 수 없는 줄 및 열 번호입니다.
이 경우 튜플 요소의 일부 또는 전부가 None일 수 있습니다.
버전 3.11의 새로운 기능.
참고 이 기능을 사용하려면 코드 개체에 열 위치를 저장해야 하므로 컴파일된 Python 파일의 디스크 사용량이나 인터프리터 메모리 사용량이 약간 증가할 수 있습니다. 추가 정보 저장을 피하거나 추가 추적 정보 인쇄를 비활성화하려면 -X no_debug_ranges 명령줄 플래그 또는 PYTHONNODEBUGRANGES 환경 변수를 사용할 수 있습니다.
Frame objects
프레임 개체는 실행 프레임을 나타냅니다. 트레이스백 객체(아래 참조)에서 발생할 수 있으며 등록된 트레이스 함수에도 전달됩니다.
특수 읽기 전용 속성: f_back은 이전 스택 프레임(호출자 쪽) 또는 이것이 맨 아래 스택 프레임인 경우 None입니다. f_code는 이 프레임에서 실행되는 코드 개체입니다. f_locals는 지역 변수를 찾는 데 사용되는 사전입니다. f_globals는 전역 변수에 사용됩니다. f_builtins는 내장(내재) 이름에 사용됩니다. f_lasti는 정확한 명령을 제공합니다(이것은 코드 객체의 바이트코드 문자열에 대한 인덱스입니다).
f_code에 액세스하면 obj 및 “f_code” 인수를 사용하여 감사 이벤트 object.__getattr__
이 발생합니다.
쓰기 가능한 특수 속성: f_trace(None이 아닌 경우)는 코드 실행 중 다양한 이벤트에 대해 호출되는 함수입니다(디버거에서 사용됨). 일반적으로 각각의 새 소스 라인에 대해 이벤트가 트리거됩니다. 이는 f_trace_lines를 False로 설정하여 비활성화할 수 있습니다.
구현 시 f_trace_opcodes를 True로 설정하여 opcode별 이벤트를 요청할 수 있습니다. 추적 함수에 의해 발생한 예외가 추적 중인 함수로 탈출하는 경우 이로 인해 정의되지 않은 인터프리터 동작이 발생할 수 있습니다.
f_lineno는 프레임의 현재 줄 번호입니다. 추적 함수 내에서 이것에 쓰면 주어진 줄로 이동합니다(맨 아래 프레임에만 해당). 디버거는 f_lineno에 기록하여 점프 명령(일명 Set Next Statement)을 구현할 수 있습니다.
프레임 개체는 한 가지 방법을 지원합니다.
frame.clear()
이 메서드는 프레임이 보유한 지역 변수에 대한 모든 참조를 지웁니다. 또한 프레임이 제너레이터에 속한 경우 제너레이터가 종료됩니다. 이는 프레임 객체와 관련된 참조 순환을 중단하는 데 도움이 됩니다(예: 예외를 포착하고 나중에 사용하기 위해 트레이스백을 저장하는 경우).
프레임이 현재 실행 중인 경우 RuntimeError가 발생합니다.
버전 3.4의 새로운 기능.
Traceback objects
역추적 객체는 예외의 스택 추적을 나타냅니다. 트레이스백 객체는 예외가 발생할 때 암시적으로 생성되며 types.TracebackType을 호출하여 명시적으로 생성될 수도 있습니다.
암시적으로 생성된 트레이스백의 경우, 예외 핸들러 검색이 실행 스택을 풀 때, 풀린 각 레벨에서 트레이스백 객체가 현재 트레이스백 앞에 삽입됩니다. 예외 핸들러가 입력되면 프로그램에서 스택 추적을 사용할 수 있습니다. (try 문 섹션을 참조하십시오.) sys.exc_info()
에 의해 반환된 튜플의 세 번째 항목 및 잡힌 예외의 __traceback__
속성으로 액세스할 수 있습니다.
프로그램에 적합한 핸들러가 없으면 스택 추적이 표준 오류 스트림에 기록됩니다(적절하게 형식화됨). 인터프리터가 대화형이면 사용자가 sys.last_traceback으로 사용할 수도 있습니다.
명시적으로 생성된 트레이스백의 경우, 전체 스택 트레이스를 형성하기 위해 tb_next 속성을 연결하는 방법을 결정하는 것은 트레이스백 생성자에게 달려 있습니다.
특수 읽기 전용 속성: tb_frame은 현재 레벨의 실행 프레임을 가리킵니다. tb_lineno는 예외가 발생한 줄 번호를 제공합니다. tb_lasti는 정확한 명령을 나타냅니다. 일치하는 except 절이 없거나 finally 절이 있는 try 문에서 예외가 발생한 경우 트레이스백의 줄 번호와 마지막 명령어는 프레임 객체의 줄 번호와 다를 수 있습니다.
tb_frame에 액세스하면 obj 및 “tb_frame” 인수를 사용하여 감사 이벤트 object.__getattr__
이 발생합니다.
쓰기 가능한 특수 속성: tb_next는 스택 추적의 다음 레벨(예외가 발생한 프레임 방향)이거나 다음 레벨이 없으면 None입니다.
버전 3.7에서 변경: 이제 트레이스백 객체를 파이썬 코드에서 명시적으로 인스턴스화할 수 있으며 기존 인스턴스의 tb_next 어트리뷰트를 업데이트할 수 있습니다.
Slice objects
슬라이스 객체는 __getitem__()
메서드에 대한 슬라이스를 나타내는 데 사용됩니다. 또한 내장된 slice() 함수에 의해 생성됩니다.
특수 읽기 전용 속성: start
는 하한값입니다. 중지는 상한입니다. 단계는 단계 값입니다. 생략하면 각각 None
입니다. 이러한 속성은 모든 유형을 가질 수 있습니다.
슬라이스 개체는 하나의 메서드를 지원합니다:
slice.indices(self, length)
이 메서드는 단일 정수 인수 길이를 사용하고 슬라이스 개체가 길이 항목 시퀀스에 적용될 경우 설명하는 슬라이스에 대한 정보를 계산합니다. 세 개의 정수로 구성된 튜플을 반환합니다. 각각 시작 및 중지 인덱스와 슬라이스의 단계 또는 보폭입니다. 누락되거나 범위를 벗어난 인덱스는 일반 슬라이스와 일치하는 방식으로 처리됩니다.
Static method objects
정적 메소드 객체는 함수 객체가 위에서 설명한 메소드 객체로 변환되지 않도록 하는 방법을 제공합니다. 정적 메서드 개체는 일반적으로 사용자 정의 메서드 개체인 다른 개체를 감싸는 래퍼입니다. 클래스 또는 클래스 인스턴스에서 정적 메서드 개체를 검색할 때 실제로 반환되는 개체는 더 이상 변환되지 않는 래핑된 개체입니다. 정적 메소드 객체도 호출 가능합니다. 정적 메소드 객체는 내장 staticmethod() 생성자에 의해 생성됩니다.
Class method objects
클래스 메서드 개체는 정적 메서드 개체와 마찬가지로 클래스 및 클래스 인스턴스에서 해당 개체를 검색하는 방식을 변경하는 다른 개체 주위의 래퍼입니다. 이러한 검색 시 클래스 메서드 개체의 동작은 위의 “사용자 정의 메서드”에 설명되어 있습니다. 클래스 메소드 객체는 내장 classmethod() 생성자에 의해 생성됩니다.
3.3. Special method names
클래스는 특수 이름을 가진 메서드를 정의하여 특수 구문(예: 산술 연산 또는 첨자 및 슬라이싱)에 의해 호출되는 특정 연산을 구현할 수 있습니다. 이것은 연산자 오버로딩에 대한 Python의 접근 방식으로, 클래스가 언어 연산자와 관련하여 자체 동작을 정의할 수 있도록 합니다. 예를 들어, 클래스가 __getitem__()
이라는 메서드를 정의하고 x가 이 클래스의 인스턴스인 경우 x[i]는 대략 type(x).__getitem__(x, i)
와 동일합니다. 언급된 경우를 제외하고 작업 실행 시도는 적절한 메서드가 정의되지 않은 경우(일반적으로 AttributeError
또는 TypeError
) 예외를 발생시킵니다.
특수 메서드를 없음으로 설정하면 해당 작업을 사용할 수 없음을 나타냅니다. 예를 들어, 클래스가 __iter__()
를 None
으로 설정하면 클래스는 반복할 수 없으므로 인스턴스에서 iter()를 호출하면 TypeError가 발생합니다(__getitem__()
으로 돌아가지 않음).
내장 유형을 에뮬레이트하는 클래스를 구현할 때 에뮬레이션은 모델링되는 개체에 적합한 정도로만 구현하는 것이 중요합니다. 예를 들어, 일부 시퀀스는 개별 요소 검색과 잘 작동할 수 있지만 슬라이스 추출은 의미가 없을 수 있습니다. (이에 대한 한 가지 예는 W3C의 문서 개체 모델의 NodeList 인터페이스입니다.)
3.3.1. Basic customization
object.__new__(cls[, …])
클래스의 새 인스턴스를 만들기 위해 호출됩니다. __new__()
는 인스턴스가 요청된 클래스를 첫 번째 인수로 취하는 정적 메서드(특별한 경우이므로 그렇게 선언할 필요가 없음)입니다. 나머지 인수는 개체 생성자 식(클래스 호출)에 전달된 인수입니다. __new__()
의 반환 값은 새 객체 인스턴스(일반적으로 cls의 인스턴스)여야 합니다.
일반적인 구현은 적절한 인수와 함께 super().__new__(cls[, …])
를 사용하여 슈퍼클래스의 __new__()
메서드를 호출한 다음 새로 생성된 인스턴스를 반환하기 전에 필요에 따라 수정하여 클래스의 새 인스턴스를 만듭니다.
객체 생성 중에 __new__()
가 호출되고 cls의 인스턴스를 반환하면 새 인스턴스의 __init__()
메서드는 __init__(self[, …])
처럼 호출됩니다. 여기서 self는 새 인스턴스이고 나머지 인수는 개체 생성자에 전달된 것과 동일합니다.
__new__()
가 cls의 인스턴스를 반환하지 않으면 새 인스턴스의__init__()
메서드가 호출되지 않습니다.
__new__()
는 주로 불변 유형(int, str 또는 튜플과 같은)의 하위 클래스가 인스턴스 생성을 사용자 정의할 수 있도록 하기 위한 것입니다. 또한 일반적으로 클래스 생성을 사용자 지정하기 위해 사용자 지정 메타클래스에서 재정의됩니다.
object.__init__(self[, …])
인스턴스가 생성된 후(__new__()
에 의해) 호출자에게 반환되기 전에 호출됩니다. 인수는 클래스 생성자 표현식에 전달된 인수입니다. 기본 클래스에 __init__()
메서드가 있는 경우 파생 클래스의 __init__()
메서드는 인스턴스의 기본 클래스 부분의 적절한 초기화를 보장하기 위해 이를 명시적으로 호출해야 합니다. 예: super().__init__([args…])
.
__new__()
와 __init__()
가 객체를 구성하는 데 함께 작동하기 때문에(객체를 생성하려면 __new__()
, 객체를 사용자 정의하려면 __init__()
), __init__()
에서 None
이 아닌 값을 반환할 수 없습니다. 그렇게 하면 런타임에 TypeError가 발생합니다.
object.__del__(self)
인스턴스가 소멸되려고 할 때 호출됩니다. 이것은 종료자 또는 (부적절하게) 소멸자라고도 합니다. 기본 클래스에 __del__() 메서드가 있는 경우 파생 클래스의 __del__() 메서드는 인스턴스의 기본 클래스 부분을 적절하게 삭제하기 위해 이를 명시적으로 호출해야 합니다.
__del__() 메서드가 인스턴스에 대한 새 참조를 생성하여 인스턴스 소멸을 연기하는 것이 가능합니다(권장하지는 않습니다!). 이것을 객체 부활이라고 합니다. 부활한 객체가 파괴되려고 할 때 __del__() 이 두 번째로 호출되는지 여부는 구현에 따라 다릅니다. 현재 CPython 구현은 한 번만 호출합니다.
인터프리터가 종료될 때 여전히 존재하는 객체에 대해 __del__() 메서드가 호출된다는 보장은 없습니다.
참고: del x는 x.__del__()을 직접 호출하지 않습니다 — 전자는 x에 대한 참조 카운트를 1씩 감소시키고 후자는 x의 참조 카운트가 0에 도달할 때만 호출됩니다.
CPython 구현 세부 사항: 참조 순환이 개체의 참조 횟수가 0이 되는 것을 방지할 수 있습니다. 이 경우 주기는 나중에 주기적 가비지 수집기에 의해 감지되고 삭제됩니다. 참조 순환의 일반적인 원인은 지역 변수에서 예외가 발생한 경우입니다. 그런 다음 프레임의 로컬은 트레이스백에서 포착된 모든 프레임의 로컬을 참조하는 자체 트레이스백을 참조하는 예외를 참조합니다.
gc 모듈에 대한 설명서도 참조하십시오.
Warning:
__del__() 메서드가 호출되는 불안정한 상황으로 인해 실행 중에 발생하는 예외는 무시되고 대신 sys.stderr에 경고가 인쇄됩니다. 특히:
• __del__()은 임의의 스레드를 포함하여 임의의 코드가 실행될 때 호출될 수 있습니다. __del__()이 잠금을 취하거나 다른 차단 리소스를 호출해야 하는 경우 __del__()을 실행하기 위해 중단된 코드가 리소스를 이미 차지했을 수 있으므로 교착 상태가 될 수 있습니다.
• __del__()은 인터프리터 종료 중에 실행될 수 있습니다. 결과적으로 액세스해야 하는 전역 변수(다른 모듈 포함)가 이미 삭제되었거나 없음으로 설정되었을 수 있습니다. Python은 이름이 단일 밑줄로 시작하는 전역이 다른 전역이 삭제되기 전에 모듈에서 삭제되도록 보장합니다. 그러한 전역에 대한 다른 참조가 존재하지 않는 경우, 이것은 가져온 모듈이 __del__() 메서드가 호출될 때 여전히 사용 가능한지 확인하는 데 도움이 될 수 있습니다.
object.__repr__(self)
객체의 “공식적인” 문자열 표현을 계산하기 위해 repr() 내장 함수에 의해 호출됩니다. 가능하다면 이것은 동일한 값을 가진 객체를 재생성하는 데 사용할 수 있는 유효한 Python 표현식처럼 보여야 합니다(적절한 환경이 제공됨). 이것이 가능하지 않으면 <…일부 유용한 설명…> 형식의 문자열이 반환되어야 합니다. 반환 값은 문자열 개체여야 합니다. 클래스가 __repr__()을 정의하지만 __str__()을 정의하지 않는 경우 해당 클래스 인스턴스의 “비공식” 문자열 표현이 필요할 때도 __repr__()이 사용됩니다.
이것은 일반적으로 디버깅에 사용되므로 표현이 정보가 풍부하고 모호하지 않은 것이 중요합니다.
object.__str__(self)
str(객체)와 내장 함수 format() 및 print()에 의해 호출되어 객체의 “비공식” 또는 멋지게 인쇄 가능한 문자열 표현을 계산합니다. 반환 값은 문자열 개체여야 합니다.
이 메서드는 __str__()이 유효한 파이썬 표현식을 반환할 것이라는 기대가 없다는 점에서 object.__repr__()과 다릅니다: 더 편리하거나 간결한 표현을 사용할 수 있습니다.
내장 유형 객체에 의해 정의된 기본 구현은 object.__repr__()을 호출합니다.
object.__bytes__(self)
객체의 바이트 문자열 표현을 계산하기 위해 바이트에 의해 호출됩니다. 바이트 객체를 반환해야 합니다.
object.__format__(self, format_spec)
format() 내장 함수에 의해 호출되고, 확장에 의해 형식이 지정된 문자열 리터럴과 str.format() 메서드의 평가가 객체의 “포맷된” 문자열 표현을 생성합니다. format_spec 인수는 원하는 형식 지정 옵션에 대한 설명이 포함된 문자열입니다. format_spec 인수의 해석은 __format__()을 구현하는 유형에 따라 다르지만 대부분의 클래스는 내장 유형 중 하나에 형식 지정을 위임하거나 유사한 형식 지정 옵션 구문을 사용합니다.
표준 형식 구문에 대한 설명은 형식 사양 미니 언어를 참조하십시오.
반환 값은 문자열 개체여야 합니다.
버전 3.4에서 변경: 객체 자체의 __format__ 메서드는 비어 있지 않은 문자열이 전달되면 TypeError 를 발생시킵니다.
버전 3.7에서 변경: object.__format__(x, ”)는 이제 format(str(x), ”)이 아니라 str(x)와 동일합니다.
object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)¶
object.__ge__(self, other)
소위 “풍부한 비교” 방법입니다. 연산자 기호와 메서드 이름 간의 대응은 다음과 같습니다. x<y는 x.__lt__(y)를 호출하고, x<=y는 x.__le__(y)를 호출하고, x==y는 x.__eq__(y)를 호출하고, x!= y는 x.__ne__(y)를 호출하고, x>y는 x.__gt__(y)를 호출하고, x>=y는 x.__ge__(y)를 호출합니다.
풍부한 비교 메서드는 지정된 인수 쌍에 대한 작업을 구현하지 않는 경우 싱글톤 NotImplemented를 반환할 수 있습니다. 규칙에 따라 성공적인 비교를 위해 False 및 True가 반환됩니다. 그러나 이러한 메서드는 모든 값을 반환할 수 있으므로 비교 연산자가 부울 컨텍스트(예: if 문의 조건)에서 사용되는 경우 Python은 값에 대해 bool()을 호출하여 결과가 참인지 거짓인지 결정합니다. .
기본적으로 객체는 is를 사용하여 __eq__()를 구현하고 잘못된 비교의 경우 NotImplemented를 반환합니다. x가 y이면 True이고 그렇지 않으면 NotImplemented입니다. __ne__()의 경우 기본적으로 __eq__()에 위임하고 NotImplemented가 아닌 한 결과를 반전시킵니다. 비교 연산자 또는 기본 구현 사이에 다른 묵시적 관계는 없습니다. 예를 들어 (x<y 또는 x==y)의 참은 x<=y를 의미하지 않습니다. 단일 루트 작업에서 순서 지정 작업을 자동으로 생성하려면 functools.total_ordering()을 참조하십시오.
사용자 지정 비교 작업을 지원하고 사전 키로 사용할 수 있는 해시 가능한 객체를 만드는 방법에 대한 몇 가지 중요한 참고 사항은 __hash__()에 대한 단락을 참조하십시오.
이러한 메서드의 교체된 인수 버전은 없습니다(왼쪽 인수는 작업을 지원하지 않지만 오른쪽 인수는 지원하는 경우 사용됨). 오히려 __lt__()와 __gt__()는 서로의 반영이고, __le__()과 __ge__()는 서로의 반영이며, __eq__()와 __ne__()은 그들 자신의 반영입니다. 피연산자의 유형이 다르고 오른쪽 피연산자의 유형이 왼쪽 피연산자 유형의 직간접 하위 클래스인 경우 오른쪽 피연산자의 반영된 메서드가 우선순위를 가지며, 그렇지 않으면 왼쪽 피연산자의 메서드가 우선순위를 갖습니다. 가상 서브클래싱은 고려되지 않습니다.
object.__hash__(self)
내장 함수 hash()에 의해 호출되며 set, frozenset 및 dict를 포함한 해시된 컬렉션의 멤버에 대한 작업을 위해 호출됩니다. __hash__() 메서드는 정수를 반환해야 합니다. 유일한 필수 속성은 동일하다고 비교되는 객체가 동일한 해시 값을 갖는다는 것입니다. 개체를 튜플로 압축하고 튜플을 해싱하여 개체 비교에서 역할을 하는 개체 구성 요소의 해시 값을 함께 혼합하는 것이 좋습니다. 예:
def __hash__(self):
return hash((self.name, self.nick, self.color))
Note
hash()
truncates the value returned from an object’s custom __hash__()
method to the size of a Py_ssize_t
. This is typically 8 bytes on 64-bit builds and 4 bytes on 32-bit builds. If an object’s __hash__()
must interoperate on builds of different bit sizes, be sure to check the width on all supported builds. An easy way to do this is with python -c "import sys; print(sys.hash_info.width)"
.
클래스가 __eq__() 메서드를 정의하지 않으면 __hash__() 작업도 정의해서는 안 됩니다. __eq__()를 정의하지만 __hash__()를 정의하지 않으면 해당 인스턴스는 해시 가능한 컬렉션의 항목으로 사용할 수 없습니다. 클래스가 변경 가능한 객체를 정의하고 __eq__() 메서드를 구현하는 경우 해시 가능한 컬렉션을 구현하려면 키의 해시 값이 변경 불가능해야 하기 때문에 __hash__()를 구현하면 안 됩니다(객체의 해시 값이 변경되면 잘못된 위치에 놓이게 됩니다) 해시 버킷).
사용자 정의 클래스에는 기본적으로 __eq__() 및 __hash__() 메서드가 있습니다. 그들과 함께, 모든 객체는 동등하지 않은 것을 비교하고(자신을 제외하고) x.__hash__()는 x == y가 x가 y이고 hash(x) == hash(y)임을 암시하는 적절한 값을 반환합니다.
__eq__()를 재정의하고 __hash__()를 정의하지 않는 클래스는 __hash__()가 암시적으로 없음으로 설정됩니다. 클래스의 __hash__() 메서드가 None이면 프로그램이 해시 값을 검색하려고 시도할 때 클래스의 인스턴스가 적절한 TypeError를 발생시키고 isinstance(obj, collections.abc.Hashable을 확인할 때 해시할 수 없는 것으로 올바르게 식별됩니다. ).
__eq__()를 재정의하는 클래스가 부모 클래스의 __hash__() 구현을 유지해야 하는 경우 인터프리터는 __hash__ = .__hash__를 설정하여 이를 명시적으로 알려야 합니다.
__eq__()를 재정의하지 않는 클래스가 해시 지원을 억제하려면 클래스 정의에 __hash__ = None을 포함해야 합니다. TypeError를 명시적으로 발생시키는 자체 __hash__()를 정의하는 클래스는 isinstance(obj, collections.abc.Hashable) 호출에 의해 해시 가능한 것으로 잘못 식별됩니다.
참고 기본적으로 str 및 bytes 객체의 __hash__() 값은 예측할 수 없는 임의의 값으로 “소금 처리”됩니다. 그것들은 개별 Python 프로세스 내에서 일정하게 유지되지만 반복되는 Python 호출 간에는 예측할 수 없습니다.
이는 사전 삽입의 최악의 성능인 O(n2) 복잡성을 악용하는 신중하게 선택된 입력으로 인해 발생하는 서비스 거부에 대한 보호를 제공하기 위한 것입니다. 자세한 내용은 http://www.ocert.org/advisories/ocert-2011-003.html을 참조하십시오.
해시 값을 변경하면 집합의 반복 순서에 영향을 줍니다. Python은 이 순서에 대해 보장하지 않습니다(일반적으로 32비트와 64비트 빌드 사이에서 다릅니다).
PYTHONHASHSEED도 참조하십시오.
버전 3.3에서 변경: 해시 무작위화는 기본적으로 활성화됩니다.
object.__bool__(self)
진리값 테스트 및 내장 연산 bool()을 구현하기 위해 호출됩니다. False 또는 True를 반환해야 합니다. 이 메서드가 정의되지 않은 경우 __len__()이 정의된 경우 호출되고 결과가 0이 아닌 경우 객체는 참으로 간주됩니다. 클래스가 __len__()도 __bool__()도 정의하지 않으면 모든 인스턴스가 참으로 간주됩니다.
3.3.2. Customizing attribute access
클래스 인스턴스에 대한 속성 액세스(x.name의 사용, 할당 또는 삭제)의 의미를 사용자 지정하기 위해 다음 메서드를 정의할 수 있습니다.
object.__getattr__(self, name)
기본 속성 액세스가 AttributeError와 함께 실패할 때 호출됩니다(name이 인스턴스 속성이 아니거나 self에 대한 클래스 트리의 속성이 아니기 때문에 __getattribute__()가 AttributeError를 발생시키거나 name 속성의 __get__()이 AttributeError를 발생시키기 때문). 이 메서드는 (계산된) 속성 값을 반환하거나 AttributeError 예외를 발생시켜야 합니다.
정상적인 메커니즘을 통해 속성이 발견되면 __getattr__()이 호출되지 않는다는 점에 유의하십시오. (이것은 __getattr__()과 __setattr__() 사이의 의도적인 비대칭입니다.) 이것은 효율성상의 이유와 그렇지 않으면 __getattr__()이 인스턴스의 다른 속성에 액세스할 방법이 없기 때문에 수행됩니다. 적어도 인스턴스 변수의 경우 인스턴스 속성 사전에 값을 삽입하지 않고 대신 다른 객체에 삽입하여 전체 제어를 위조할 수 있습니다. 속성 액세스를 실제로 완전히 제어하는 방법은 아래의 __getattribute__() 메서드를 참조하십시오.
object.__getattribute__(self, name)
클래스의 인스턴스에 대한 속성 액세스를 구현하기 위해 무조건 호출됩니다. 클래스가 __getattr__()도 정의하는 경우 __getattribute__()가 명시적으로 호출하거나 AttributeError를 발생시키지 않는 한 후자는 호출되지 않습니다. 이 메서드는 (계산된) 속성 값을 반환하거나 AttributeError 예외를 발생시켜야 합니다. 이 메서드에서 무한 재귀를 방지하려면 구현 시 항상 동일한 이름으로 기본 클래스 메서드를 호출하여 필요한 속성(예: object.__getattribute__(self, name))에 액세스해야 합니다.
언어 구문 또는 내장 함수를 통한 암시적 호출의 결과로 특수 메서드를 조회할 때 이 메서드는 여전히 우회될 수 있습니다. 특수 메서드 조회를 참조하세요.
특정 민감한 속성 액세스의 경우 obj 및 name 인수를 사용하여 감사 이벤트 객체.__getattr__을 발생시킵니다.
object.__setattr__(self, name, value)
속성 할당을 시도할 때 호출됩니다. 이것은 일반적인 메커니즘(즉, 인스턴스 사전에 값을 저장) 대신에 호출됩니다. name은 속성 이름이고 value는 할당할 값입니다.
__setattr__()이 인스턴스 어트리뷰트에 할당하려는 경우 동일한 이름을 가진 기본 클래스 메서드를 호출해야 합니다(예: object.__setattr__(self, name, value)).
특정 민감한 속성 할당의 경우 obj, name, value 인수를 사용하여 감사 이벤트 object.__setattr__을 발생시킵니다.
object.__delattr__(self, name)
__setattr__()과 비슷하지만 할당 대신 속성을 삭제합니다. 이는 del obj.name이 개체에 의미가 있는 경우에만 구현해야 합니다.
특정 민감한 속성 삭제의 경우 obj 및 name 인수를 사용하여 감사 이벤트 객체.__delattr__을 발생시킵니다.
object.__dir__(self)¶
객체에서 dir()이 호출될 때 호출됩니다. 시퀀스를 반환해야 합니다. dir()은 반환된 시퀀스를 목록으로 변환하고 정렬합니다.
3.3.2.1. Customizing module attribute access
특수 이름 __getattr__ 및 __dir__을 사용하여 모듈 속성에 대한 액세스를 사용자 정의할 수도 있습니다. 모듈 수준의 __getattr__ 함수는 속성의 이름인 하나의 인수를 수락하고 계산된 값을 반환하거나 AttributeError를 발생시켜야 합니다. 일반적인 조회를 통해 모듈 객체에서 속성을 찾을 수 없는 경우, 즉 object.__getattribute__(), AttributeError를 발생시키기 전에 모듈 __dict__에서 __getattr__을 검색합니다. 찾으면 속성 이름으로 호출하고 결과를 반환합니다.
__dir__ 함수는 인수를 허용하지 않고 모듈에서 액세스할 수 있는 이름을 나타내는 일련의 문자열을 반환해야 합니다. 있는 경우 이 함수는 모듈에 대한 표준 dir() 검색을 재정의합니다.
모듈 동작(속성, 속성 설정 등)을 보다 세밀하게 사용자 지정하려면 모듈 객체의 __class__ 속성을 types.ModuleType의 하위 클래스로 설정할 수 있습니다. 예를 들어:
import sys
from types import ModuleType
class VerboseModule(ModuleType):
def __repr__(self):
return f'Verbose {self.__name__}'
def __setattr__(self, attr, value):
print(f'Setting {attr}...')
super().__setattr__(attr, value)
sys.modules[__name__].__class__ = VerboseModule
정의 모듈 __getattr__ 및 설정 모듈 __class__는 어트리뷰트 액세스 구문을 사용하여 만든 조회에만 영향을 미칩니다. 모듈 전역에 직접 액세스(모듈 내의 코드를 통해 또는 모듈의 전역 사전에 대한 참조를 통해)는 영향을 받지 않습니다.
버전 3.5에서 변경: __class__ 모듈 속성은 이제 쓰기 가능합니다.
버전 3.7의 새로운 기능: __getattr__ 및 __dir__ 모듈 속성.
또한보십시오 PEP 562 – 모듈 __getattr__ 및 __dir__ 모듈의 __getattr__ 및 __dir__ 함수에 대해 설명합니다.
3.3.2.2. Implementing Descriptors
다음 메서드는 메서드를 포함하는 클래스의 인스턴스(소위 설명자 클래스)가 소유자 클래스에 나타날 때만 적용됩니다(설명자는 소유자의 클래스 사전 또는 부모 중 하나의 클래스 사전에 있어야 함). 아래 예에서 “속성”은 이름이 소유자 클래스 ‘__dict__에 있는 속성의 키인 속성을 나타냅니다.
object.__get__(self, instance, owner=None)
소유자 클래스(클래스 속성 액세스) 또는 해당 클래스의 인스턴스(인스턴스 속성 액세스)의 속성을 가져오기 위해 호출됩니다. 선택적 소유자 인수는 소유자 클래스이고 instance는 속성에 액세스한 인스턴스이거나 소유자를 통해 속성에 액세스한 경우 None입니다.
이 메서드는 계산된 속성 값을 반환하거나 AttributeError 예외를 발생시켜야 합니다.
PEP 252는 __get__()이 하나 또는 두 개의 인수로 호출 가능하도록 지정합니다. 파이썬 자체 내장 설명자가 이 사양을 지원합니다. 그러나 일부 타사 도구에는 두 인수가 모두 필요한 설명자가 있을 수 있습니다. 파이썬 자체의 __getattribute__() 구현은 필요 여부에 관계없이 항상 두 인수를 모두 전달합니다.
object.__set__(self, instance, value)
소유자 클래스의 인스턴스 인스턴스에 대한 속성을 새 값인 value로 설정하기 위해 호출됩니다.
__set__() 또는 __delete__()를 추가하면 설명자의 종류가 “데이터 설명자”로 변경됩니다. 자세한 내용은 설명자 호출을 참조하십시오.
object.__delete__(self, instance)
소유자 클래스의 인스턴스 인스턴스에서 특성을 삭제하기 위해 호출됩니다.
__objclass__ 속성은 이 객체가 정의된 클래스를 지정하는 것으로 inspect 모듈에 의해 해석됩니다(이를 적절하게 설정하면 동적 클래스 속성의 런타임 검사에 도움이 될 수 있습니다). 콜러블의 경우, 주어진 유형(또는 하위 클래스)의 인스턴스가 첫 번째 위치 인수로 예상되거나 필요함을 나타낼 수 있습니다(예를 들어, CPython은 C로 구현된 바인딩되지 않은 메서드에 대해 이 특성을 설정함).
3.3.2.3. Invoking Descriptors
일반적으로 디스크립터는 “바인딩 동작”이 있는 객체 속성이며 속성 액세스는 디스크립터 프로토콜의 메서드(__get__(), __set__() 및 __delete__())에 의해 재정의되었습니다. 이러한 메서드 중 하나가 개체에 대해 정의된 경우 해당 메서드를 설명자라고 합니다.
속성 액세스의 기본 동작은 객체의 사전에서 속성을 가져오거나 설정하거나 삭제하는 것입니다. 예를 들어, a.x에는 a.__dict__[‘x’]로 시작하여 type(a).__dict__[‘x’]로 시작하고 메타클래스를 제외한 type(a)의 기본 클래스를 통해 계속되는 조회 체인이 있습니다.
그러나 조회한 값이 디스크립터 메서드 중 하나를 정의하는 객체인 경우 Python은 기본 동작을 재정의하고 대신 디스크립터 메서드를 호출할 수 있습니다. 우선 순위 체인에서 이것이 발생하는 위치는 정의된 설명자 메서드와 호출 방법에 따라 다릅니다.
디스크립터 호출의 시작점은 바인딩 a.x입니다. 인수가 어셈블되는 방법은 다음에 따라 다릅니다.
Direct Call
가장 간단하고 덜 일반적인 호출은 사용자 코드가 x.__get__(a)와 같이 설명자 메서드를 직접 호출할 때입니다.
Instance Binding
객체 인스턴스에 바인딩하는 경우 a.x는 type(a).__dict__[‘x’].__get__(a, type(a)) 호출로 변환됩니다.
Class Binding
클래스에 바인딩하는 경우 A.x는 A.__dict__[‘x’].__get__(None, A) 호출로 변환됩니다.
Super Binding
super(A, a).x와 같은 점선 조회는 a.__class__.__mro__에서 A 다음의 기본 클래스 B를 검색한 다음 B.__dict__[‘x’].__get__(a, A)를 반환합니다. 디스크립터가 아니면 x가 변경되지 않은 상태로 반환됩니다.
인스턴스 바인딩의 경우 설명자 호출의 우선 순위는 정의된 설명자 메서드에 따라 다릅니다. 디스크립터는 __get__(), __set__() 및 __delete__()의 모든 조합을 정의할 수 있습니다. __get__()을 정의하지 않는 경우 객체의 인스턴스 사전에 값이 없으면 속성에 액세스하면 디스크립터 객체 자체를 반환합니다. 디스크립터가 __set__() 및/또는 __delete__()를 정의하면 데이터 디스크립터입니다. 둘 다 정의하지 않으면 데이터 디스크립터가 아닙니다. 일반적으로 데이터 디스크립터는 __get__() 및 __set__()을 모두 정의하는 반면 비데이터 디스크립터에는 __get__() 메서드만 있습니다. __get__() 및 __set__() (및/또는 __delete__())가 정의된 데이터 디스크립터는 항상 인스턴스 사전의 재정의를 재정의합니다. 대조적으로, 비 데이터 디스크립터는 인스턴스에 의해 재정의될 수 있습니다.
Python 메서드(@staticmethod 및 @classmethod로 장식된 메서드 포함)는 비데이터 설명자로 구현됩니다. 따라서 인스턴스는 메서드를 재정의하고 재정의할 수 있습니다. 이렇게 하면 개별 인스턴스가 동일한 클래스의 다른 인스턴스와 다른 동작을 얻을 수 있습니다.
property() 함수는 데이터 설명자로 구현됩니다. 따라서 인스턴스는 속성의 동작을 재정의할 수 없습니다.
3.3.2.4. __slots__
__slots__를 사용하면 데이터 멤버(속성 등)를 명시적으로 선언하고 __dict__ 및 __weakref__ 생성을 거부할 수 있습니다(__slots__에서 명시적으로 선언하거나 부모에서 사용할 수 있는 경우 제외).
__dict__를 사용하여 절약된 공간은 상당할 수 있습니다. 속성 조회 속도도 크게 향상될 수 있습니다.
object.__slots__
이 클래스 변수는 인스턴스에서 사용되는 변수 이름이 있는 문자열, 반복 가능 또는 일련의 문자열을 할당할 수 있습니다. __slots__는 선언된 변수를 위한 공간을 예약하고 각 인스턴스에 대한 __dict__ 및 __weakref__의 자동 생성을 방지합니다.
3.3.2.4.1. Notes on using __slots__
- __slots__가 없는 클래스에서 상속할 때 인스턴스의 __dict__ 및 __weakref__ 속성에 항상 액세스할 수 있습니다.
- __dict__ 변수가 없으면 인스턴스에 __slots__ 정의에 나열되지 않은 새 변수를 할당할 수 없습니다. 목록에 없는 변수 이름에 할당하려고 하면 AttributeError가 발생합니다. 새 변수의 동적 할당이 필요한 경우 __slots__ 선언의 문자열 시퀀스에 ‘__dict__’를 추가합니다.
- 각 인스턴스에 대한 __weakref__ 변수가 없으면 __slots__를 정의하는 클래스는 해당 인스턴스에 대한 약한 참조를 지원하지 않습니다. 약한 참조 지원이 필요한 경우 __slots__ 선언의 문자열 시퀀스에 ‘__weakref__’를 추가합니다.
- __슬롯__은 각 변수 이름에 대한 설명자를 생성하여 클래스 수준에서 구현됩니다. 결과적으로 클래스 속성은 __slots__로 정의된 인스턴스 변수의 기본값을 설정하는 데 사용할 수 없습니다. 그렇지 않으면 class 속성이 설명자 할당을 덮어씁니다.
- __slots__ 선언의 동작은 그것이 정의된 클래스로 제한되지 않습니다. 부모 클래스에서 선언된 __slots__은 자식 클래스에서 사용할 수 있습니다. 그러나 하위 하위 클래스는 __slots__(추가 슬롯의 이름만 포함해야 함)도 정의하지 않는 한 __dict__ 및 __weakref__를 가져옵니다.
- 클래스가 기본 클래스에도 정의된 슬롯을 정의하는 경우 기본 클래스 슬롯에 의해 정의된 인스턴스 변수에 액세스할 수 없습니다(기본 클래스에서 해당 설명자를 직접 검색하는 경우 제외). 이것은 정의되지 않은 프로그램의 의미를 렌더링합니다. 향후에는 이를 방지하기 위한 검사가 추가될 수 있습니다.
- 비어 있지 않은 __slots__는 int, bytes 및 tuple과 같은 “가변 길이” 내장 유형에서 파생된 클래스에 대해 작동하지 않습니다.
- 문자열이 아닌 모든 iterable은 __slots__에 할당될 수 있습니다.
- __slots__를 할당하기 위해 사전을 사용하는 경우 사전 키가 슬롯 이름으로 사용됩니다. 사전의 값은 inspect.getdoc()에서 인식하고 help()의 출력에 표시되는 속성별 docstring을 제공하는 데 사용할 수 있습니다.
- __class__ 할당은 두 클래스가 동일한 __slots__를 가진 경우에만 작동합니다.
- 여러 개의 슬롯이 있는 상위 클래스를 사용한 다중 상속을 사용할 수 있지만 하나의 상위만 슬롯에 의해 생성된 특성을 가질 수 있습니다(다른 기반에는 빈 슬롯 레이아웃이 있어야 함). 위반 시 TypeError가 발생합니다.
- 반복자가 __slots__에 사용되면 각 반복자의 값에 대해 설명자가 생성됩니다. 그러나 __slots__ 속성은 빈 반복자가 됩니다.
3.3.3. Customizing class creation
클래스가 다른 클래스에서 상속될 때마다 __init_subclass__()가 부모 클래스에서 호출됩니다. 이런 식으로 하위 클래스의 동작을 변경하는 클래스를 작성할 수 있습니다. 이것은 클래스 데코레이터와 밀접하게 관련되어 있지만 클래스 데코레이터가 적용되는 특정 클래스에만 영향을 미치는 경우 __init_subclass__는 메서드를 정의하는 클래스의 향후 하위 클래스에만 적용됩니다.
object.__init_subclass__(cls)
이 메서드는 포함하는 클래스가 서브클래싱될 때마다 호출됩니다. cls는 새 하위 클래스입니다. 일반 인스턴스 메서드로 정의된 경우 이 메서드는 암시적으로 클래스 메서드로 변환됩니다.
새 클래스에 주어진 키워드 인수는 부모 클래스 __init_subclass__로 전달됩니다. __init_subclass__를 사용하는 다른 클래스와의 호환성을 위해 다음과 같이 필요한 키워드 인수를 제거하고 나머지는 기본 클래스로 전달해야 합니다.
class Philosopher:
def __init_subclass__(cls, /, default_name, **kwargs):
super().__init_subclass__(**kwargs)
cls.default_name = default_name
class AustralianPhilosopher(Philosopher, default_name="Bruce"):
pass
기본 구현 object.__init_subclass__는 아무 작업도 수행하지 않지만 인수를 사용하여 호출하면 오류가 발생합니다.
참고 메타클래스 힌트 메타클래스는 나머지 형식 기계에서 사용되며 __init_subclass__ 구현으로 전달되지 않습니다. 명시적 힌트가 아닌 실제 메타클래스는 type(cls)로 액세스할 수 있습니다.
버전 3.6의 새로운 기능.
클래스가 생성되면 type.__new__()는 클래스 변수를 스캔하고 __set_name__() 후크가 있는 변수에 대한 콜백을 만듭니다.
object.__set_name__(self, owner, name)
소유 클래스 소유자가 생성될 때 자동으로 호출됩니다. 개체는 해당 클래스의 이름에 할당되었습니다.
class A:
x = C() # Automatically calls: x.__set_name__(A, 'x')
클래스가 생성된 후에 클래스 변수가 할당되면 __set_name__() 이 자동으로 호출되지 않습니다. 필요한 경우 __set_name__()을 직접 호출할 수 있습니다.
class A:
pass
c = C()
A.x = c # The hook is not called
c.__set_name__(A, 'x') # Manually invoke the hook
자세한 내용은 클래스 개체 만들기를 참조하세요.
버전 3.6의 새로운 기능.
3.3.3.1. Metaclasses
기본적으로 클래스는 type()을 사용하여 구성됩니다. 클래스 본문은 새 네임스페이스에서 실행되고 클래스 이름은 type(name, bases, namespace)의 결과에 로컬로 바인딩됩니다.
클래스 생성 프로세스는 클래스 정의 행에 메타클래스 키워드 인수를 전달하거나 그러한 인수를 포함하는 기존 클래스에서 상속하여 사용자 정의할 수 있습니다. 다음 예제에서 MyClass와 MySubclass는 모두 Meta의 인스턴스입니다.
class Meta(type):
pass
class MyClass(metaclass=Meta):
pass
class MySubclass(MyClass):
pass
클래스 정의에 지정된 다른 모든 키워드 인수는 아래에 설명된 모든 메타클래스 작업으로 전달됩니다.
클래스 정의가 실행되면 다음 단계가 발생합니다.
- MRO 항목이 해결됩니다.
- 적절한 메타클래스가 결정됩니다.
- 클래스 네임스페이스가 준비되었습니다.
- 클래스 본문이 실행됩니다.
- 클래스 개체가 생성됩니다.
3.3.3.2. Resolving MRO entries
클래스 정의에 나타나는 기반이 유형의 인스턴스가 아닌 경우 __mro_entries__ 메서드가 검색됩니다. 발견되면 원래 기본 튜플과 함께 호출됩니다. 이 메서드는 이 기본 대신 사용될 클래스의 튜플을 반환해야 합니다. 튜플은 비어 있을 수 있으며, 이 경우 원래 베이스는 무시됩니다.
PEP 560 – 타이핑 모듈 및 일반 유형에 대한 핵심 지원도 참조하십시오.
3.3.3.3. Determining the appropriate metaclass
클래스 정의에 적합한 메타클래스는 다음과 같이 결정됩니다.
- 베이스와 명시적 메타클래스가 제공되지 않으면 type()이 사용됩니다.
- 명시적 메타클래스가 제공되고 type()의 인스턴스가 아닌 경우 메타클래스로 직접 사용됩니다.
- type()의 인스턴스가 명시적 메타클래스로 제공되거나 베이스가 정의된 경우 가장 많이 파생된 메타클래스가 사용됩니다.
가장 많이 파생된 메타클래스는 명시적으로 지정된 메타클래스(있는 경우)와 지정된 모든 기본 클래스의 메타클래스(즉, type(cls))에서 선택됩니다. 가장 많이 파생된 메타클래스는 이러한 모든 후보 메타클래스의 하위 유형입니다. 후보 메타클래스 중 어느 것도 해당 기준을 충족하지 않으면 클래스 정의가 TypeError와 함께 실패합니다.
3.3.3.4. Preparing the class namespace
적절한 메타클래스가 식별되면 클래스 네임스페이스가 준비됩니다. 메타클래스에 __prepare__ 속성이 있으면 namespace = metaclass.__prepare__(name, bases, **kwds) (여기서 추가 키워드 인수가 있는 경우 클래스 정의에서 가져옴)라고 합니다. __prepare__ 메서드는 클래스 메서드로 구현되어야 합니다. __prepare__에 의해 반환된 네임스페이스는 __new__에 전달되지만 최종 클래스 객체가 생성될 때 네임스페이스는 새 사전에 복사됩니다.
메타클래스에 __prepare__ 속성이 없으면 클래스 네임스페이스는 비어 있는 정렬된 매핑으로 초기화됩니다.
See alsoPEP 3115 – Metaclasses in Python 3000 (Introduced the __prepare__
namespace hook)
3.3.3.5. Executing the class body
클래스 본문은 (대략) exec(body, globals(), namespace)로 실행됩니다. exec()에 대한 일반 호출과의 주요 차이점은 어휘 범위 지정을 통해 클래스 정의가 함수 내에서 발생할 때 클래스 본문(모든 메서드 포함)이 현재 및 외부 범위의 이름을 참조할 수 있다는 것입니다.
그러나 클래스 정의가 함수 내에서 발생하더라도 클래스 내에서 정의된 메서드는 여전히 클래스 범위에서 정의된 이름을 볼 수 없습니다. 클래스 변수는 인스턴스 또는 클래스 메서드의 첫 번째 매개 변수를 통해 또는 다음 섹션에서 설명하는 암시적 어휘 범위 __class__ 참조를 통해 액세스해야 합니다.
3.3.3.6. Creating the class object
클래스 본문을 실행하여 클래스 네임스페이스가 채워지면 metaclass(name, bases, namespace, **kwds)를 호출하여 클래스 객체가 생성됩니다(여기서 전달되는 추가 키워드는 __prepare__에 전달된 키워드와 동일함).
이 클래스 개체는 인수가 없는 형식의 super()에서 참조할 개체입니다. __class__는 클래스 본문의 메서드가 __class__ 또는 super를 참조하는 경우 컴파일러에 의해 생성된 암시적 클로저 참조입니다. 이렇게 하면 인수가 없는 형식의 super()가 어휘 범위 지정을 기반으로 정의되는 클래스를 올바르게 식별할 수 있으며, 현재 호출을 만드는 데 사용된 클래스 또는 인스턴스는 메서드에 전달된 첫 번째 인수를 기반으로 식별됩니다.
CPython 구현 세부 정보: CPython 3.6 이상에서 __class__ 셀은 클래스 네임스페이스의 __classcell__ 항목으로 메타클래스에 전달됩니다. 있는 경우 클래스가 올바르게 초기화되려면 type.__new__ 호출까지 전파되어야 합니다. 그렇게 하지 않으면 Python 3.8에서 RuntimeError가 발생합니다.
기본 메타클래스 유형 또는 궁극적으로 type.__new__를 호출하는 메타클래스를 사용하는 경우 클래스 객체를 생성한 후 다음과 같은 추가 사용자 지정 단계가 호출됩니다.
- type.__new__ 메서드는 __set_name__() 메서드를 정의하는 클래스 네임스페이스의 모든 속성을 수집합니다.
- 이러한 __set_name__ 메서드는 정의되는 클래스와 해당 특정 속성의 할당된 이름으로 호출됩니다.
- __init_subclass__() 훅은 메서드 결정 순서에 따라 새 클래스의 직계 부모에서 호출됩니다.
클래스 객체가 생성되면 클래스 정의(있는 경우)에 포함된 클래스 데코레이터로 전달되고 결과 객체는 정의된 클래스로 로컬 네임스페이스에 바인딩됩니다.
type.__new__에 의해 새로운 클래스가 생성되면 네임스페이스 매개변수로 제공된 객체가 새로 정렬된 매핑에 복사되고 원래 객체는 삭제됩니다. 새 사본은 클래스 객체의 __dict__ 속성이 되는 읽기 전용 프록시로 래핑됩니다.
See alsoPEP 3135 – New super (Describes the implicit __class__
closure reference)
3.3.3.7. Uses for metaclasses
메타클래스의 잠재적 용도는 무한합니다. 탐색된 몇 가지 아이디어에는 열거형, 로깅, 인터페이스 검사, 자동 위임, 자동 속성 생성, 프록시, 프레임워크 및 자동 리소스 잠금/동기화가 포함됩니다.
3.3.4. Customizing instance and subclass checks
다음 메서드는 isinstance() 및 issubclass() 내장 함수의 기본 동작을 재정의하는 데 사용됩니다.
특히 메타클래스 abc.ABCMeta는 다른 ABC를 포함하여 모든 클래스 또는 유형(내장 유형 포함)에 “가상 기본 클래스”로 ABC(추상 기본 클래스)를 추가할 수 있도록 이러한 메서드를 구현합니다.
class.__instancecheck__(self, instance)
인스턴스가 클래스의 (직접 또는 간접) 인스턴스로 간주되어야 하는 경우 true를 반환합니다. 정의된 경우 isinstance(instance, class)를 구현하기 위해 호출됩니다.
class.__subclasscheck__(self, subclass)
하위 클래스가 클래스의 (직접 또는 간접) 하위 클래스로 간주되어야 하는 경우 true를 반환합니다. 정의된 경우 issubclass(subclass, class)를 구현하기 위해 호출됩니다.
이러한 메서드는 클래스의 유형(메타클래스)에서 조회됩니다. 실제 클래스에서 클래스 메서드로 정의할 수 없습니다. 이는 인스턴스에서 호출되는 특수 메서드 조회와 일치하며, 이 경우에만 인스턴스 자체가 클래스입니다.
See also: PEP 3119 – Introducing Abstract Base Classes
__instancecheck__() 및 __subclasscheck__()를 통해 isinstance() 및 issubclass() 동작을 사용자 지정하기 위한 사양을 포함하며, 언어에 추상 기본 클래스(abc 모듈 참조)를 추가하는 맥락에서 이 기능에 대한 동기를 부여합니다.
3.3.5. Emulating generic types
유형 주석을 사용할 때 Python의 대괄호 표기법을 사용하여 일반 유형을 매개변수화하는 것이 종종 유용합니다. 예를 들어 list[int] 주석은 모든 요소가 int 유형인 목록을 나타내는 데 사용될 수 있습니다.
See also
PEP 484 – Type Hints
유형 주석을 위한 Python 프레임워크 소개
Generic Alias Types
매개변수화된 제네릭 클래스를 나타내는 개체에 대한 설명서
Generics, user-defined generics and typing.Generic
런타임에 매개변수화할 수 있고 정적 유형 검사기가 이해할 수 있는 제네릭 클래스를 구현하는 방법에 대한 문서입니다.
클래스는 일반적으로 특수 클래스 메서드 __class_getitem__()을 정의하는 경우에만 매개 변수화할 수 있습니다.
classmethod object.__class_getitem__(cls, key)
키에서 찾은 유형 인수로 일반 클래스의 특수화를 나타내는 객체를 반환합니다.
클래스에 정의된 경우 __class_getitem__()은 자동으로 클래스 메서드입니다. 따라서 정의할 때 @classmethod로 장식할 필요가 없습니다.
3.3.5.1. The purpose of __class_getitem__
__class_getitem__() 의 목적은 이러한 클래스에 유형 힌트를 더 쉽게 적용하기 위해 표준 라이브러리 일반 클래스의 런타임 매개변수화를 허용하는 것입니다.
런타임에 매개변수화할 수 있고 정적 유형 검사기가 이해할 수 있는 사용자 지정 제네릭 클래스를 구현하려면 사용자는 이미 __class_getitem__()을 구현하는 표준 라이브러리 클래스에서 상속하거나 __class_getitem__(의 자체 구현이 있는 typing.Generic에서 상속해야 합니다. ).
표준 라이브러리 외부에서 정의된 클래스에 대한 __class_getitem__()의 사용자 정의 구현은 mypy와 같은 타사 유형 검사기에서 이해하지 못할 수 있습니다. 유형 힌트 이외의 목적으로 모든 클래스에서 __class_getitem__() 을 사용하는 것은 권장되지 않습니다.
3.3.5.2. __class_getitem__ versus __getitem__
일반적으로 대괄호를 사용한 객체 구독은 객체의 클래스에 정의된 __getitem__() 인스턴스 메서드를 호출합니다. 그러나 구독 중인 개체 자체가 클래스인 경우 클래스 메서드 __class_getitem__()이 대신 호출될 수 있습니다. __class_getitem__()은 적절하게 정의된 경우 GenericAlias 객체를 반환해야 합니다.
표현식 obj[x]와 함께 제공되는 파이썬 인터프리터는 다음 프로세스와 같은 것을 따라 __getitem__() 또는 __class_getitem__()을 호출해야 하는지 여부를 결정합니다:
from inspect import isclass
def subscribe(obj, x):
"""Return the result of the expression 'obj[x]'"""
class_of_obj = type(obj)
# If the class of obj defines __getitem__,
# call class_of_obj.__getitem__(obj, x)
if hasattr(class_of_obj, '__getitem__'):
return class_of_obj.__getitem__(obj, x)
# Else, if obj is a class and defines __class_getitem__,
# call obj.__class_getitem__(x)
elif isclass(obj) and hasattr(obj, '__class_getitem__'):
return obj.__class_getitem__(x)
# Else, raise an exception
else:
raise TypeError(
f"'{class_of_obj.__name__}' object is not subscriptable"
)
Python에서 모든 클래스는 그 자체로 다른 클래스의 인스턴스입니다. 클래스의 클래스는 해당 클래스의 메타클래스로 알려져 있으며 대부분의 클래스에는 유형 클래스가 메타클래스로 있습니다. type은 __getitem__()을 정의하지 않습니다. 즉, list[int], dict[str, float] 및 tuple[str, bytes]와 같은 표현식은 모두 __class_getitem__()이 호출되는 결과를 낳습니다:
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> type(dict) == type(list) == type(tuple) == type(str) == type(bytes)
True
>>> # "list[int]" calls "list.__class_getitem__(int)"
>>> list[int]
list[int]
>>> # list.__class_getitem__ returns a GenericAlias object:
>>> type(list[int])
<class 'types.GenericAlias'>
그러나 클래스에 __getitem__()을 정의하는 사용자 정의 메타클래스가 있는 경우 클래스를 구독하면 다른 동작이 발생할 수 있습니다. 이에 대한 예는 enum 모듈에서 찾을 수 있습니다:
>>> from enum import Enum
>>> class Menu(Enum):
... """A breakfast menu"""
... SPAM = 'spam'
... BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
See also
PEP 560 – 타이핑 모듈 및 제네릭 유형에 대한 핵심 지원
__class_getitem__() 소개 및 구독으로 인해 __getitem__() 대신 __class_getitem__()이 호출되는 경우 개요
3.3.6. Emulating callable objects
object.__call__(self[, args…])
인스턴스가 함수로 “호출”될 때 호출됩니다. 이 메서드가 정의된 경우 x(arg1, arg2, …)는 대략 type(x).__call__(x, arg1, …)으로 변환됩니다.
3.3.7. Emulating container types
컨테이너 개체를 구현하기 위해 다음 메서드를 정의할 수 있습니다. 컨테이너는 일반적으로 시퀀스(예: 목록 또는 튜플) 또는 매핑(예: 사전)이지만 다른 컨테이너도 나타낼 수 있습니다. 첫 번째 메서드 집합은 시퀀스를 에뮬레이트하거나 매핑을 에뮬레이트하는 데 사용됩니다. 차이점은 시퀀스의 경우 허용 가능한 키는 0 <= k < N인 정수 k(여기서 N은 시퀀스의 길이 또는 항목 범위를 정의하는 슬라이스 개체)여야 한다는 것입니다. 또한 매핑이 동작하는 메서드 keys(), values(), items(), get(), clear(), setdefault(), pop(), popitem(), copy() 및 update() 메서드를 제공하는 것이 좋습니다. Python의 표준 사전 객체와 유사합니다. collections.abc 모듈은 MutableMapping 추상 기본 클래스를 제공하여 __getitem__(), __setitem__(), __delitem__() 및 keys()의 기본 집합에서 해당 메서드를 만드는 데 도움을 줍니다. 변경 가능한 시퀀스는 Python 표준 목록 객체와 같은 메소드 append(), count(), index(), extend(), insert(), pop(), remove(), reverse() 및 sort()를 제공해야 합니다. 마지막으로 시퀀스 유형은 아래에 설명된 __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() 및 __imul__() 메서드를 정의하여 덧셈(연결을 의미) 및 곱셈(반복을 의미)을 구현해야 합니다. 다른 숫자 연산자를 정의하면 안 됩니다. in 연산자를 효율적으로 사용할 수 있도록 매핑과 시퀀스 모두 __contains__() 메서드를 구현하는 것이 좋습니다. 매핑의 경우 in은 매핑의 키를 검색해야 합니다. 시퀀스의 경우 값을 통해 검색해야 합니다. 또한 매핑과 시퀀스 모두 __iter__() 메서드를 구현하여 컨테이너 전체를 효율적으로 반복할 수 있도록 하는 것이 좋습니다. 매핑의 경우 __iter__() 는 객체의 키를 통해 반복해야 합니다. 시퀀스의 경우 값을 반복해야 합니다.
object.__len__(self)
내장 함수 len()을 구현하기 위해 호출됩니다. 객체의 길이, 정수 >= 0을 반환해야 합니다. 또한 __bool__() 메서드를 정의하지 않고 __len__() 메서드가 0을 반환하는 객체는 부울 컨텍스트에서 거짓으로 간주됩니다.
CPython 구현 세부 정보: CPython에서 길이는 최대 sys.maxsize여야 합니다. 길이가 sys.maxsize보다 크면 일부 기능(예: len())이 OverflowError를 일으킬 수 있습니다. 진리값 테스트로 OverflowError가 발생하는 것을 방지하려면 객체가 __bool__() 메서드를 정의해야 합니다.
object.__length_hint__(self)
operator.length_hint()를 구현하기 위해 호출됩니다. 개체의 예상 길이를 반환해야 합니다(실제 길이보다 크거나 작을 수 있음). 길이는 정수 >= 0이어야 합니다. 반환 값은 NotImplemented일 수도 있으며, 이는 __length_hint__ 메서드가 전혀 존재하지 않는 것과 동일하게 취급됩니다. 이 방법은 순전히 최적화이며 정확성을 위해 필요하지 않습니다.
버전 3.4의 새로운 기능.
참고: 슬라이싱은 다음 세 가지 방법으로 독점적으로 수행됩니다.
다음과 같은 호출은:
a[1:2] = b
아래와 같이 해석됩니다.
a[slice(1, 2, None)] = b
기타 등등. 누락된 슬라이스 항목은 항상 None으로 채워집니다.
object.__getitem__(self, key)
self[key] 평가를 구현하기 위해 호출됩니다. 시퀀스 유형의 경우 허용되는 키는 정수 및 슬라이스 객체여야 합니다. 음수 인덱스의 특별한 해석(클래스가 시퀀스 유형을 에뮬레이트하려는 경우)은 __getitem__() 메서드에 달려 있음에 유의하십시오. 키가 부적절한 유형이면 TypeError가 발생할 수 있습니다. 시퀀스에 대한 인덱스 집합 외부의 값인 경우(음수 값의 특수 해석 후), IndexError 가 발생해야 합니다. 매핑 유형의 경우 키가 누락된 경우(컨테이너에 없음) KeyError가 발생해야 합니다.
참고: for 루프는 시퀀스의 끝을 적절하게 감지할 수 있도록 잘못된 인덱스에 대해 IndexError가 발생할 것으로 예상합니다.
참고: 클래스를 첨자로 작성할 때 __getitem__() 대신 특수 클래스 메서드 __class_getitem__()을 호출할 수 있습니다. 자세한 내용은 __class_getitem__versus__getitem__을 참조하십시오.
object.__setitem__(self, key, value)
self[key]에 대한 할당을 구현하기 위해 호출됩니다. __getitem__()과 동일한 참고 사항입니다. 개체가 키 값에 대한 변경을 지원하거나 새 키를 추가할 수 있는 경우 또는 요소를 교체할 수 있는 경우 시퀀스에 대해 매핑에 대해서만 구현해야 합니다. __getitem__() 메서드에 대해 부적절한 키 값에 대해 동일한 예외가 발생해야 합니다.
object.__delitem__(self, key)
self[key] 삭제를 구현하기 위해 호출됩니다. __getitem__()과 동일한 참고 사항입니다. 개체가 키 제거를 지원하는 경우 매핑에 대해서만 구현하거나 시퀀스에서 요소를 제거할 수 있는 경우 시퀀스에 대해 구현해야 합니다. __getitem__() 메서드에 대해 부적절한 키 값에 대해 동일한 예외가 발생해야 합니다.
object.__missing__(self, key)
key가 딕셔너리에 없을 때 dict 하위 클래스에 대해 self[key]를 구현하기 위해 dict.__getitem__()에 의해 호출됩니다.
object.__iter__(self)
이 메서드는 컨테이너에 iterator가 필요할 때 호출됩니다. 이 메서드는 컨테이너의 모든 개체를 반복할 수 있는 새 iterator 개체를 반환해야 합니다. Mapping의 경우 컨테이너의 키를 반복해야 합니다.
object.__reversed__(self)
역방향 반복을 구현하기 위해 reversed() 내장에 의해 호출됩니다(있는 경우). 컨테이너의 모든 개체를 역순으로 반복하는 새 반복자 개체를 반환해야 합니다.
__reversed__() 메서드가 제공되지 않으면, reversed() 내장은 시퀀스 프로토콜(__len__() 및 __getitem__())을 사용하도록 대체됩니다. 시퀀스 프로토콜을 지원하는 객체는 reversed()에서 제공하는 것보다 더 효율적인 구현을 제공할 수 있는 경우에만 __reversed__()를 제공해야 합니다.
멤버십 테스트 연산자(in 및 not in)는 일반적으로 컨테이너를 통한 반복으로 구현됩니다. 그러나 컨테이너 개체는 개체가 반복 가능할 필요가 없는 보다 효율적인 구현으로 다음과 같은 특수 메서드를 제공할 수 있습니다.
object.__contains__(self, item)
멤버십 테스트 연산자를 구현하기 위해 호출됩니다. item이 self에 있으면 true를 반환하고 그렇지 않으면 false를 반환해야 합니다. 매핑 개체의 경우 값이나 key-item 쌍이 아닌 매핑의 키를 고려해야 합니다.
__contains__()를 정의하지 않는 객체의 경우, 멤버십 테스트는 먼저 __iter__()를 통해 반복을 시도한 다음 __getitem__()을 통해 이전 시퀀스 반복 프로토콜을 시도합니다. 언어 참조의 이 섹션을 참조하세요.
3.3.8. Emulating numeric types
숫자 개체를 에뮬레이트하기 위해 다음 메서드를 정의할 수 있습니다. 구현된 특정 종류의 숫자가 지원하지 않는 연산에 해당하는 메서드(예: 정수가 아닌 숫자에 대한 비트 연산)는 정의되지 않은 상태로 두어야 합니다.
object.__add__(self, other)
object.__sub__(self, other)
object.__mul__(self, other)
object.__matmul__(self, other)
object.__truediv__(self, other)
object.__floordiv__(self, other)
object.__mod__(self, other)
object.__divmod__(self, other)
object.__pow__(self, other[, modulo])
object.__lshift__(self, other)
object.__rshift__(self, other)
object.__and__(self, other)
object.__xor__(self, other)
object.__or__(self, other)
이러한 메서드는 이진 산술 연산(+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |)을 구현하기 위해 호출됩니다. 예를 들어, 표현식 x + y를 평가하려면 여기서 x는 __add__() 메서드가 있는 클래스의 인스턴스이고 type(x).__add__(x, y)가 호출됩니다. __divmod__() 메서드는 __floordiv__() 및 __mod__()를 사용하는 것과 동일해야 합니다. __truediv__()와 관련이 없어야 합니다. 내장 pow() 함수의 삼항 버전을 지원하려면 __pow__()가 선택적 세 번째 인수를 허용하도록 정의해야 합니다.
이러한 메서드 중 하나가 제공된 인수를 사용한 작업을 지원하지 않는 경우 NotImplemented를 반환해야 합니다.
object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
object.__rmatmul__(self, other)
object.__rtruediv__(self, other)¶
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
object.__rdivmod__(self, other)
object.__rpow__(self, other[, modulo])
object.__rlshift__(self, other)
object.__rrshift__(self, other)
object.__rand__(self, other)
object.__rxor__(self, other)
object.__ror__(self, other)
이 메서드는 이진 산술 연산(+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |)을 구현하기 위해 호출됩니다. 반영된(교체된) 피연산자. 이 함수는 왼쪽 피연산자가 해당 연산 3을 지원하지 않고 피연산자의 유형이 다른 경우에만 호출됩니다. 4 예를 들어, 표현식 x – y를 평가하기 위해 y는 __rsub__() 메서드가 있는 클래스의 인스턴스이고, type(y).__rsub__(y, x)는 type(x).__sub__(x , y)는 NotImplemented를 반환합니다.
삼항 pow()는 rpow() 호출을 시도하지 않습니다(강제 규칙이 너무 복잡해짐).
참고: 오른쪽 피연산자의 유형이 왼쪽 피연산자의 유형의 하위 클래스이고 해당 하위 클래스가 연산에 대해 반영된 메서드의 다른 구현을 제공하는 경우 이 메서드는 왼쪽 피연산자의 반영되지 않은 메서드보다 먼저 호출됩니다. 이 동작을 통해 하위 클래스는 조상의 작업을 재정의할 수 있습니다.
object.__iadd__(self, other)
object.__isub__(self, other)
object.__imul__(self, other)
object.__imatmul__(self, other)
object.__itruediv__(self, other)
object.__ifloordiv__(self, other)
object.__imod__(self, other)
object.__ipow__(self, other[, modulo])
object.__ilshift__(self, other)¶
object.__irshift__(self, other)
object.__iand__(self, other)
object.__ixor__(self, other)
object.__ior__(self, other)
이러한 메서드는 증가된 산술 할당(+=, -=, *=, @=, /=, //=, %=, **=, <<=, >>=, &=, ^=을 구현하기 위해 호출됩니다. , |=). 이러한 메서드는 작업을 제자리에서 시도하고(self 수정) 결과를 반환해야 합니다(self일 수 있지만 반드시 그럴 필요는 없음). 특정 메서드가 정의되지 않은 경우 추가 할당은 일반 메서드로 대체됩니다. 예를 들어 x가 __iadd__() 메서드가 있는 클래스의 인스턴스인 경우 x += y는 x = x.__iadd__(y) 와 동일합니다. 그렇지 않으면 x + y의 평가와 마찬가지로 x.__add__(y) 및 y.__radd__(x)가 고려됩니다. 특정 상황에서 증강 할당은 예기치 않은 오류를 유발할 수 있지만(왜 a_tuple[i] += [‘item’]이 추가가 작동할 때 예외를 발생시키나요? 참조) 이 동작은 사실 데이터 모델의 일부입니다.
object.__neg__(self)
object.__pos__(self)
object.__abs__(self)
object.__invert__(self)
단항 산술 연산(-, +, abs() 및 ~)을 구현하기 위해 호출됩니다.
object.__complex__(self)
object.__int__(self)
object.__float__(self)
내장 함수 complex(), int() 및 float()를 구현하기 위해 호출됩니다. 적절한 유형의 값을 반환해야 합니다.
object.__index__(self)¶
operator.index()를 구현하기 위해 그리고 파이썬이 숫자 객체를 정수 객체로 무손실로 변환해야 할 때마다 호출됩니다(예: 슬라이싱 또는 내장 bin(), hex() 및 oct() 함수에서). 이 메서드가 있으면 숫자 개체가 정수 유형임을 나타냅니다. 정수를 반환해야 합니다.
__int__(), __float__() 및 __complex__()가 정의되지 않은 경우 해당 내장 함수 int(), float() 및 complex()는 __index__()로 대체됩니다.
object.__round__(self[, ndigits])
object.__trunc__(self)
object.__floor__(self)
object.__ceil__(self)
내장 함수 round() 및 수학 함수 trunc(), floor() 및 ceil()을 구현하기 위해 호출됩니다. ndigits가 __round__()에 전달되지 않는 한 이 모든 메서드는 Integral(일반적으로 int)으로 잘린 객체의 값을 반환해야 합니다.
내장 함수 int()는 __int__()도 __index__()도 정의되지 않은 경우 __trunc__()로 돌아갑니다.
버전 3.11에서 변경: int()에서 __trunc__()로의 위임은 더 이상 사용되지 않습니다.
3.3.9. With Statement Context Managers
컨텍스트 관리자는 with 문을 실행할 때 설정할 런타임 컨텍스트를 정의하는 객체입니다. 컨텍스트 관리자는 코드 블록 실행을 위해 원하는 런타임 컨텍스트로의 진입과 종료를 처리합니다. 컨텍스트 관리자는 일반적으로 with 문(with 문 섹션에서 설명)을 사용하여 호출되지만 메서드를 직접 호출하여 사용할 수도 있습니다.
컨텍스트 관리자의 일반적인 용도에는 다양한 종류의 전역 상태 저장 및 복원, 리소스 잠금 및 잠금 해제, 열린 파일 닫기 등이 포함됩니다.
컨텍스트 관리자에 대한 자세한 내용은 컨텍스트 관리자 유형을 참조하세요.
object.__enter__(self)
이 개체와 관련된 런타임 컨텍스트를 입력합니다. with 문은 이 메서드의 반환 값을 문의 as 절에 지정된 대상(있는 경우)에 바인딩합니다.
object.__exit__(self, exc_type, exc_value, traceback)
이 개체와 관련된 런타임 컨텍스트를 종료합니다. 매개변수는 컨텍스트를 종료하게 만든 예외를 설명합니다. 컨텍스트가 예외 없이 종료된 경우 세 인수 모두 None이 됩니다.
예외가 제공되고 메서드가 예외를 억제하려는 경우(즉, 전파되지 않도록 방지) true 값을 반환해야 합니다. 그렇지 않으면 이 메서드를 종료할 때 예외가 정상적으로 처리됩니다.
__exit__() 메서드는 전달된 예외를 다시 발생시키지 않아야 합니다. 이것은 발신자의 책임입니다.
See also:PEP 343 – The “with” statement
Python with 문에 대한 사양, 배경 및 예제입니다.
3.3.10. Customizing positional arguments in class pattern matching
패턴에서 클래스 이름을 사용할 때 패턴의 위치 인수는 기본적으로 허용되지 않습니다. 즉, case MyClass(x, y)는 일반적으로 MyClass에서 특별한 지원 없이 유효하지 않습니다. 그런 종류의 패턴을 사용하려면 클래스에서 __match_args__ 속성을 정의해야 합니다.
object.__match_args__
이 클래스 변수에 문자열 튜플을 할당할 수 있습니다. 이 클래스가 위치 인수가 있는 클래스 패턴에서 사용되면 각 위치 인수는 __match_args__의 해당 값을 키워드로 사용하여 키워드 인수로 변환됩니다. 이 속성이 없으면 ()로 설정하는 것과 같습니다.
예를 들어 MyClass.__match_args__가 (“left”, “center”, “right”)인 경우 MyClass(x, y) 케이스는 MyClass(left=x, center=y) 케이스와 동일합니다. 패턴의 인수 수는 __match_args__의 요소 수보다 작거나 같아야 합니다. 더 크면 패턴 일치 시도에서 TypeError가 발생합니다.
버전 3.10의 새로운 기능.
See also: PEP 634 – Structural Pattern Matching
Python match
문에 대한 사양입니다.
3.3.11. Special method lookup
사용자 지정 클래스의 경우 특수 메서드의 암시적 호출은 객체의 인스턴스 사전이 아니라 객체의 유형에 정의된 경우에만 올바르게 작동하도록 보장됩니다. 이 동작은 다음 코드에서 예외를 발생시키는 이유입니다.
>>> class C:
... pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len()
이 동작의 근거는 유형 객체를 포함한 모든 객체에 의해 구현되는 __hash__() 및 __repr__()과 같은 여러 특수 메서드에 있습니다. 이러한 메서드의 암시적 조회가 기존 조회 프로세스를 사용하는 경우 형식 개체 자체에서 호출될 때 실패합니다.
>>> 1 .__hash__() == hash(1)
True
>>> int.__hash__() == hash(int)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor '__hash__' of 'int' object needs an argument
이러한 방식으로 클래스의 바인딩되지 않은 메서드를 잘못 호출하려고 시도하는 것을 ‘메타클래스 혼동’이라고 하며 특수 메서드를 찾을 때 인스턴스를 우회하여 피할 수 있습니다.
>>> type(1).__hash__(1) == hash(1)
True
>>> type(int).__hash__(int) == hash(int)
True
정확성을 위해 인스턴스 어트리뷰트를 우회하는 것 외에도 암시적 특수 메서드 조회는 일반적으로 객체의 메타클래스에서도 __getattribute__() 메서드를 우회합니다.
>>> class Meta(type):
... def __getattribute__(*args):
... print("Metaclass getattribute invoked")
... return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print("Class getattribute invoked")
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Explicit lookup via instance Class getattribute invoked
10
>>> type(c).__len__(c) # Explicit lookup via type Metaclass getattribute invoked
10
>>> len(c) # Implicit lookup
10
이러한 방식으로 __getattribute__() 기계를 우회하면 특수 메서드 처리에 약간의 유연성을 희생하면서 인터프리터 내에서 속도 최적화를 위한 상당한 범위를 제공합니다(특수 메서드는 클래스 객체 자체에 설정되어야 일관되게 호출할 수 있습니다. 통역사).
3.4. Coroutines
3.4.1. Awaitable Objects
어웨이터블 객체는 일반적으로 __await__() 메서드를 구현합니다. async def 함수에서 반환된 코루틴 객체는 대기 가능합니다.
참고: types.coroutine()으로 데코레이트된 제너레이터에서 반환된 제너레이터 이터레이터 객체도 어웨이터블이지만 __await__()를 구현하지는 않습니다.
object.__await__(self)
반복자를 반환해야 합니다. 대기 가능한 개체를 구현하는 데 사용해야 합니다. 예를 들어, asyncio.Future는 await 표현식과 호환되도록 이 메서드를 구현합니다.
참고: 이 언어는 __await__에 의해 반환된 반복자가 생성한 객체의 유형이나 값에 제한을 두지 않습니다. 이는 대기 가능한 객체를 관리할 비동기 실행 프레임워크(예: asyncio)의 구현에 고유하기 때문입니다.
버전 3.5의 새로운 기능.
See also
대기 가능한 객체에 대한 추가 정보는 PEP 492를 참조하십시오.
3.4.2. Coroutine Objects
코루틴 객체는 어웨이터블 객체입니다. 코루틴의 실행은 __await__()를 호출하고 결과를 반복하여 제어할 수 있습니다. 코루틴이 실행을 마치고 반환하면 반복자는 StopIteration을 발생시키고 예외의 값 속성은 반환 값을 보유합니다. 코루틴이 예외를 발생시키면 반복자에 의해 전파됩니다. 코루틴은 처리되지 않은 StopIteration 예외를 직접 발생시키지 않아야 합니다.
코루틴에는 또한 생성기의 메서드와 유사한 아래 나열된 메서드가 있습니다(Generator-iterator 메서드 참조). 그러나 제너레이터와 달리 코루틴은 반복을 직접 지원하지 않습니다.
버전 3.5.2에서 변경: 코루틴에서 두 번 이상 기다리는 것은 RuntimeError입니다.
coroutine.send(value)
코루틴 실행을 시작하거나 재개합니다. 값이 없음이면, 이것은 __await__()에 의해 반환된 이터레이터를 진행시키는 것과 같습니다. 값이 None이 아니면 이 메서드는 코루틴을 일시 중단하게 만든 반복자의 send() 메서드에 위임합니다. 결과(반환 값, StopIteration 또는 기타 예외)는 위에서 설명한 __await__() 반환 값을 반복할 때와 동일합니다.
coroutine.throw(value)
coroutine.throw(type[, value[, traceback]])
코루틴에서 지정된 예외를 발생시킵니다. 이 메서드는 해당 메서드가 있는 경우 코루틴을 일시 중단하게 만든 반복자의 throw() 메서드에 위임합니다. 그렇지 않으면 일시 중단 지점에서 예외가 발생합니다. 결과(반환 값, StopIteration 또는 기타 예외)는 위에서 설명한 await() 반환 값을 반복할 때와 동일합니다. 코루틴에서 예외가 포착되지 않으면 호출자에게 다시 전파됩니다.
coroutine.close()
코루틴이 스스로 정리하고 종료하도록 합니다. 코루틴이 정지된 경우 이 메서드는 먼저 코루틴을 정지시킨 반복자의 close() 메서드(해당 메서드가 있는 경우)에 위임합니다. 그런 다음 중단 지점에서 GeneratorExit를 발생시켜 코루틴이 즉시 스스로 정리하도록 합니다. 마지막으로 코루틴은 시작되지 않았더라도 실행이 완료된 것으로 표시됩니다.
코루틴 객체는 파괴되려고 할 때 위의 프로세스를 사용하여 자동으로 닫힙니다.
3.4.3. Asynchronous Iterators
비동기 이터레이터는 __anext__ 메서드에서 비동기 코드를 호출할 수 있습니다.
비동기 반복자는 async for 문에서 사용할 수 있습니다.
object.__aiter__(self)
비동기 이터레이터 객체를 반환해야 합니다.
object.__anext__(self)
Iterator의 다음 값을 결과로 나타내는 awaitable을 반환해야 합니다. 반복이 끝나면 StopAsyncIteration 오류를 발생시켜야 합니다.
비동기 반복 가능 객체의 예:
class Reader:
async def readline(self):
...
def __aiter__(self):
return self
async def __anext__(self):
val = await self.readline()
if val == b'':
raise StopAsyncIteration
return val
버전 3.5의 새로운 기능.
버전 3.7에서 변경: Python 3.7 이전에는 __aiter__() 가 비동기 이터레이터로 확인되는 어웨이터블을 반환할 수 있었습니다.
파이썬 3.7부터 __aiter__()는 비동기 이터레이터 객체를 반환해야 합니다. 다른 것을 반환하면 TypeError 오류가 발생합니다.
3.4.4. Asynchronous Context Managers
비동기 컨텍스트 관리자는 __aenter__ 및 __aexit__ 메서드에서 실행을 일시 중단할 수 있는 컨텍스트 관리자입니다.
비동기 컨텍스트 관리자는 async with 문에서 사용할 수 있습니다.
object.__aenter__(self)
__enter__()와 의미상 유사하지만 어웨이터블을 반환해야 한다는 유일한 차이점이 있습니다.
object.__aexit__(self, exc_type, exc_value, traceback)
어웨이터블을 반환해야 한다는 점만 제외하면 __exit__()와 의미상 유사합니다.
비동기 컨텍스트 관리자 클래스의 예:
class AsyncContextManager:
async def __aenter__(self):
await log('entering context')
async def __aexit__(self, exc_type, exc, tb):
await log('exiting context')
버전 3.5의 새로운 기능.
Source: https://docs.python.org/3/reference/datamodel.html