이 글은 "__missing__()" 함수와 관련된 문제를 주로 소개하는 python에 대한 관련 지식을 제공합니다. 이 마법의 기능을 함께 살펴보겠습니다.
추천 학습: python 학습 튜토리얼
일반 사전에서 값을 가져올 때 키가 존재하지 않을 수 있습니다:
dd = {'name':'PythonCat'} dd.get('age') # 结果:None dd.get('age', 18) # 结果:18 dd['age'] # 报错 KeyError dd.__getitem__('age') # 等同于 dd['age']
가져오기 () 메서드에는 반환 값이 있고, 키가 없을 때 두 번째 매개 변수를 반환 내용으로 전달할 수 있으므로 허용됩니다. 그러나 다른 두 가지 쓰기 방법에서는 오류가 보고됩니다.
후자의 두 가지 작성 방법의 문제를 해결하기 위해 __missing__() 매직 방법을 사용할 수 있습니다.
이제 다음과 같은 요청이 있다고 가정해 보겠습니다. 사전에서 특정 키에 해당하는 값을 가져오고, 값이 있으면 값을 반환하고, 값이 없으면 키를 삽입하고, 기본값을 지정합니다(예: 빈 목록으로).
네이티브 dict를 사용하면 구현하기가 쉽지 않습니다. 그러나 Python은 사용하기 매우 쉬운 확장 클래스 collections.defaultdict
를 제공합니다. collections.defaultdict
:
如图所示,当取不存在的 key 时,没有再报 KeyError,而是默认存入到字典中。
为什么 defaultdict 可以做到这一点呢?
原因是 defaultdict 在继承了内置类型 dict 之后,还定义了一个 __missing__() 方法,当 __getitem__取不存在的值时,它就会调用入参中传入的工厂函数(上例是调用 list(),创建空列表)。
作为最典型的示例,defaultdict 在文档注释中写到:
简而言之,__missing__()的主要作用就是由__getitem__在缺失 key 时调用,从而避免出现 KeyError。
另外一个典型的使用例子是collections.Counter
,它也是 dict 的子类,在取未被统计的 key 时,返回计数 0:
由上可知,__missing__()在__getitem__()取不到值时会被调用,但是,我不经意间还发现了一个细节:__getitem__()在取不到值时,并不一定会调用__missing__()。
这是因为它并非内置类型的必要属性,并没有在字典基类中被预先定义。
如果你直接从 dict 类型中取该属性值,会报属性不存在:AttributeError: type object 'object' has no attribute '__missing__'
defaultdict가 왜 이런 일을 할 수 있나요?
그 이유는 defaultdict가 내장 유형 dict를 상속한 후 __missing__() 메서드도 정의하기 때문입니다. __getitem__이 존재하지 않는 값을 취하면 입력 매개 변수에 전달된 팩토리 함수를 호출합니다(위의 예는 Call입니다). list(), 빈 목록 생성).
가장 일반적인 예로서 defaultdict는 문서 주석에 다음과 같이 씁니다:
간단히 말하면, __missing__()의 주요 함수는 키가 누락되었을 때 __getitem__에 의해 호출되어 KeyError를 방지하는 것입니다.
또 다른 일반적인 사용 예는 dict의 하위 클래스이기도 한collections.Counter
입니다. 계산되지 않은 키를 사용하면 개수가 0으로 반환됩니다.
2.
가능한 한 위에서 볼 수 있듯이 __getitem__()이 값을 얻을 수 없을 때 __missing__()이 호출됩니다. 그러나 우연히 세부 사항을 발견했습니다:__getitem__()은 값을 얻을 수 없을 때 반드시 __missing__(을 호출하지는 않습니다.)
내장형의 필수 속성도 아니고 딕셔너리 기반 클래스에 미리 정의되어 있지도 않기 때문입니다.dict 유형에서 직접 속성 값을 가져오면 속성이 존재하지 않는다고 보고됩니다: AttributeError: type object 'object' has no attribute '__missing__'
.
그리고 이것은 흥미롭습니다. 내장 유형의 하위 클래스에만 존재하는 마법 메서드, 전체 Python 세계를 살펴보면 아마도 두 번째 예를 찾기가 어려울 것입니다.
갑자기 연상이 생겼습니다. 이 파악하기 어려운 __missing__()은 "살아있는 사람을 변화시키는" 데 능숙한 마술사와 같습니다. 먼저 관객이 외부 유리(예: 공식 문서)를 통해 그를 볼 수 있도록 하세요. 열면 그는 내부에 있지 않으며(즉, 내장 유형) props가 변경되면 다시 그대로 나타납니다(즉, dict의 하위 클래스).
__missing__()의 마법은 "마법" 자체 외에도 강력한 "마법"이 필요합니다.
지난 기사에서 네이티브 매직 메서드는 C 언어 인터페이스에서 동일한 핵심 논리를 가질 수 있지만 Python 언어 인터페이스에는 호출 관계가 없다는 것을 발견했습니다.
Magic 이러한 종류의 메소드 "비접촉" 성능은 일반적인 코드 재사용 원칙을 위반하며 내장 유형의 하위 클래스가 이상한 동작을 하는 이유이기도 합니다.
공식 Python에서는 매직 메서드를 재사용하는 것보다 새로운 UserString, UserList 및 UserDict 하위 클래스를 제공하는 것이 합리적일 수 있습니다. 유일한 합리적인 설명은 매직 메서드를 서로 호출하는 데 드는 비용이 너무 높다는 것입니다.
그러나 특별한 경우인 __missing__()의 경우 Python은 타협하고 이 대가를 지불해야 합니다!
__missing__()은 마법 메서드의 "2등급 시민"입니다. 독립적인 호출 항목이 없으며 __getitem__()에 의해 수동적으로만 호출될 수 있습니다. 즉, __missing__()은 __getitem__()에 따라 다릅니다.
__init__(), __enter__(), __len__(), __eq__() 등과 같은 "일류 시민"과는 달리 객체 수명 주기 또는 실행의 특정 노드에서 트리거됩니다. 프로세스는 내장 함수나 연산자에 의해 트리거되며 상대적으로 독립적인 이벤트이며 종속성이 없습니다.
__missing__()은 메서드 호출을 수행하기 위해 __getitem__()에 의존하고 __getitem__()도 완전한 기능을 수행하기 위해 __missing__()에 의존합니다.
이를 달성하기 위해 __getitem__()은 인터프리터 코드에서 백도어를 열고 C 언어 인터페이스에서 Python 인터페이스로 돌아와 "__missing__"이라는 특정 메서드를 호출합니다.
그리고 이것이 진짜 "마술"입니다. 지금까지는 __missing__()만이 그러한 치료를 즐기는 유일한 마술 방법인 것 같습니다!
Python의 사전은 값을 얻기 위한 두 가지 내장 메서드, 즉 __getitem__()과 get()을 제공합니다. 값이 존재하지 않으면 처리 전략이 다릅니다. 전자는 오류를 보고합니다. >KeyError, None을 반환합니다. KeyError
,而后者会返回 None。
为什么 Python 要提供两个不同的方法呢?或者应该问,为什么 Python 要令这两个方法做出不一样的处理呢?
这可能有一个很复杂(也可能是很简单)的解释,本文暂不深究了。
不过有一点是可以确定的:即原生 dict 类型简单粗暴地抛KeyError
왜 Python은 두 가지 다른 방법을 제공하나요? 아니면 왜 Python이 이 두 메서드를 다르게 처리하는지 물어봐야 할까요?
설명이 매우 복잡할 수도 있고 매우 간단할 수도 있으므로 이 글에서는 다루지 않겠습니다. 하지만 한 가지는 확실합니다. 기본 dict 유형은 간단하고 거칠게 KeyError
를 발생시킵니다.
사전 유형에 더 강력한 성능을 제공하기 위해(또는 __getitem__()이 get()처럼 작동하도록) Python에서는 사전의 하위 클래스에서 __getitem__()이 검색하고 호출할 수 있도록 __missing__()을 정의할 수 있습니다.
이 기사에서는 __missing__()의 구현 원칙을 정리하여 눈에 띄지 않는 존재가 아니라는 사실을 드러냅니다. 매직 메소드 간의 장벽을 허물고 다른 매직 메소드에 의해 호출되는 것을 지원하는 유일한 특수 사례입니다!
🎜매직 메서드의 독립성을 유지하기 위해 Python은 UserString, UserList 및 UserDict와 같은 파생 클래스를 도입하는 데 많은 노력을 기울였지만 __missing__()의 경우 타협을 선택했습니다. 🎜🎜추천 학습: 🎜python 튜토리얼🎜🎜위 내용은 Python 마법 함수 학습 __missing__의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!