목차
Iterator size" >Iterator size
매우 모호하고 거의 사용되지 않는 것처럼 보이지만 실제로는 SQLAlchemy 또는 Flask Views와 같은 API를 구축할 때 일반적으로 사용되기 때문에 여러 번 접했을 수도 있습니다. " >매우 모호하고 거의 사용되지 않는 것처럼 보이지만 실제로는 SQLAlchemy 또는 Flask Views와 같은 API를 구축할 때 일반적으로 사용되기 때문에 여러 번 접했을 수도 있습니다.
自省(introspection)" >自省(introspection)
魔法属性" >魔法属性
创建自己魔法方法?" >创建自己魔法方法?
백엔드 개발 파이썬 튜토리얼 Python의 매직 메소드

Python의 매직 메소드

Apr 13, 2023 am 10:25 AM
python 연산자

Python의 Magic 메소드는 클래스에 "magic"을 추가할 수 있는 특수 메소드입니다. 종종 두 개의 밑줄로 둘러싸여 이름이 지정됩니다.

Python의 매직 메소드

Dunder(이중 밑줄) 방법으로도 알려진 Python의 마법 방법입니다. 대부분의 경우 생성자(init), 문자열 표현(str, repr) 또는 산술 연산자(add/mul)와 같은 간단한 작업에 이를 사용합니다. 사실, 들어보지 못했을 수도 있지만 매우 유용한 메서드가 많이 있습니다. 이 기사에서는 이러한 마법의 메서드를 정리하겠습니다.

Iterator size

우리 모두는 __len__ 메서드를 알고 있습니다. 컨테이너 클래스에 len() 함수를 구현합니다. 하지만 반복자를 구현하는 클래스 객체의 길이를 얻으려면 어떻게 해야 할까요?

it = iter(range(100))
 print(it.__length_hint__())
 # 100
 next(it)
 print(it.__length_hint__())
 # 99
 
 a = [1, 2, 3, 4, 5]
 it = iter(a)
 print(it.__length_hint__())
 # 5
 next(it)
 print(it.__length_hint__())
 # 4
 a.append(6)
 print(it.__length_hint__())
 # 5
로그인 후 복사

위와 같이 반복자(생성자가 아님)에 내장된 메서드인 __length_hint__ 메서드를 구현하기만 하면 됩니다. 볼 수 있으며 동적 길이 변경도 지원합니다. 그러나 이름 그대로 이는 단지 힌트일 뿐이며 완전히 정확하다고 보장되지는 않습니다. 목록 반복자의 경우 정확한 결과를 얻을 수 있지만 다른 반복자의 경우 확실하지 않습니다. 그러나 정확하지 않더라도 PEP 424에 설명된 대로 필요한 정보를 얻는 데 도움이 될 수 있습니다.

length_hint는 정수(그렇지 않으면 TypeError가 발생함) 또는 NotImplemented를 반환해야 하며 정확할 필요는 없으며 컨테이너의 실제 크기보다 크거나 작은 값을 반환할 수 있습니다. NotImplemented는 유한 길이 추정이 없음을 나타냅니다. 음수 값을 반환하지 않을 수 있습니다(그렇지 않으면 ValueError가 발생함). 관련, 메타프로그래밍은 매일 사용해야 하는 것이 아닐 수 있지만 이를 사용하기 위한 몇 가지 편리한 트릭이 있습니다. 그러한 트릭 중 하나는 __init_subclass__를 메타클래스를 처리할 필요 없이 기본 클래스의 기능을 확장하는 지름길로 사용하는 것입니다.

 class Pet:
def __init_subclass__(cls, /, default_breed, **kwargs):
super().__init_subclass__(**kwargs)
cls.default_breed = default_breed
 
 class Dog(Pet, default_name="German Shepherd"):
pass
로그인 후 복사
위의 코드에서는 하위 클래스를 정의할 때 설정할 수 있는 기본 클래스에 키워드 인수를 추가합니다. . 실제 사용 사례는 단순히 속성에 할당하는 것이 아니라 제공된 매개변수를 처리하려는 경우 이 메서드를 사용하는 것입니다.

매우 모호하고 거의 사용되지 않는 것처럼 보이지만 실제로는 SQLAlchemy 또는 Flask Views와 같은 API를 구축할 때 일반적으로 사용되기 때문에 여러 번 접했을 수도 있습니다.

또 다른 메타클래스 매직 메소드는 __call__입니다. 이 메소드를 사용하면 클래스 인스턴스가 호출될 때 발생하는 일을 사용자 정의할 수 있습니다.

 class CallableClass:
def __call__(self, *args, **kwargs):
print("I was called!")
 
 instance = CallableClass()
 
 instance()
 # I was called!
로그인 후 복사

이 메소드를 사용하여 호출할 수 없는 클래스를 만들 수 있습니다.

 class NoInstances(type):
def __call__(cls, *args, **kwargs):
raise TypeError("Can't create instance of this class")
 
 class SomeClass(metaclass=NoInstances):
@staticmethod
def func(x):
print('A static method')
 
 instance = SomeClass()
 # TypeError: Can't create instance of this class
로그인 후 복사

정적 메소드만 있는 클래스의 경우 이 메소드는 인스턴스를 생성하지 않고 사용됩니다. 수업.

또 다른 유사한 시나리오는 싱글톤 패턴입니다. 클래스는 최대 하나의 인스턴스만 가질 수 있습니다.

 class Singleton(type):
def __init__(cls, *args, **kwargs):
cls.__instance = None
super().__init__(*args, **kwargs)
 
def __call__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = super().__call__(*args, **kwargs)
return cls.__instance
else:
return cls.__instance
 
 class Logger(metaclass=Singleton):
def __init__(self):
print("Creating global Logger instance")
로그인 후 복사

싱글턴 클래스에는 비공개 __인스턴스가 있습니다. 그렇지 않은 경우 생성 및 할당되고, 이미 존재하는 경우 반환만 됩니다. .

클래스가 있고 __init__을 호출하지 않고 해당 클래스의 인스턴스를 만들고 싶다고 가정해 보세요. __new__ 메소드가 도움이 될 수 있습니다:

 class Document:
def __init__(self, text):
self.text = text
 
 bare_document = Document.__new__(Document)
 print(bare_document.text)
 # AttributeError: 'Document' object has no attribute 'text'
 
 setattr(bare_document, "text", "Text of the document")
로그인 후 복사

어떤 경우에는 인스턴스를 생성하는 일반적인 프로세스를 우회해야 할 수도 있습니다. 위의 코드는 이를 수행하는 방법을 보여줍니다. Document(…)를 호출하는 대신 __init__을 호출하지 않고 기본 인스턴스를 생성하는 Document.__new__(Document)를 호출합니다. 따라서 인스턴스의 속성(이 경우 텍스트)은 초기화되지 않으므로 추가적으로 setattr 함수를 사용하여 값을 할당해야 합니다(매직 메소드 __setattr__이기도 함).

왜 이러는 걸까요? 다음과 같이 생성자를 대체하고 싶을 수도 있기 때문입니다.

 class Document:
def __init__(self, text):
self.text = text
 
@classmethod
def from_file(cls, file): # Alternative constructor
d = cls.__new__(cls)
# Do stuff...
return d
로그인 후 복사

from_file 메소드는 생성자 역할을 하며 먼저 __new__를 사용하여 인스턴스를 생성한 다음 __init__를 호출하지 않고 구성합니다.

메타 프로그래밍과 관련된 다음 마법의 방법은 __getattr__입니다. 이 메서드는 일반적인 속성 액세스에 실패할 때 호출됩니다. 이는 누락된 메서드에 대한 액세스/호출을 다른 클래스에 위임하는 데 사용할 수 있습니다.

 class String:
def __init__(self, value):
self._value = str(value)
 
def custom_operation(self):
pass
 
def __getattr__(self, name):
return getattr(self._value, name)
 
 s = String("some text")
 s.custom_operation() # Calls String.custom_operation()
 print(s.split()) # Calls String.__getattr__("split") and delegates to str.split
 # ['some', 'text']
 
 print("some text" + "more text")
 # ... works
 print(s + "more text")
 # TypeError: unsupported operand type(s) for +: 'String' and 'str'
로그인 후 복사

문자열의 사용자 정의 구현을 정의하기 위해 클래스에 몇 가지 추가 함수(예: 위의 custom_Operation)를 추가하려고 합니다. 하지만 분할, 조인, 대문자화 등과 같은 모든 문자열 메서드를 다시 구현하고 싶지는 않습니다. 여기서는 __getattr__을 사용하여 기존 문자열 메서드를 호출할 수 있습니다.

이 방법은 일반 메서드에서 작동하지만 위의 예에서 연결과 같은 작업을 제공하는 매직 메서드 __add__는 위임되지 않습니다. 따라서 우리가 그것들도 작동하도록 하려면 그것들을 다시 구현해야 합니다.

自省(introspection)

最后一个与元编程相关的方法是__getattribute__。它一个看起来非常类似于前面的__getattr__,但是他们有一个细微的区别,__getattr__只在属性查找失败时被调用,而__getattribute__是在尝试属性查找之前被调用。

所以可以使用__getattribute__来控制对属性的访问,或者你可以创建一个装饰器来记录每次访问实例属性的尝试:

 def logger(cls):
original_getattribute = cls.__getattribute__
 
def getattribute(self, name):
print(f"Getting: '{name}'")
return original_getattribute(self, name)
 
cls.__getattribute__ = getattribute
return cls
 
 @logger
 class SomeClass:
def __init__(self, attr):
self.attr = attr
 
def func(self):
...
 
 instance = SomeClass("value")
 instance.attr
 # Getting: 'attr'
 instance.func()
 # Getting: 'func'
로그인 후 복사

装饰器函数logger 首先记录它所装饰的类的原始__getattribute__方法。然后将其替换为自定义方法,该方法在调用原始的__getattribute__方法之前记录了被访问属性的名称。

魔法属性

到目前为止,我们只讨论了魔法方法,但在Python中也有相当多的魔法变量/属性。其中一个是__all__:

 # some_module/__init__.py
 __all__ = ["func", "some_var"]
 
 some_var = "data"
 some_other_var = "more data"
 
 def func():
return "hello"
 
 # -----------
 
 from some_module import *
 
 print(some_var)
 # "data"
 print(func())
 # "hello"
 
 print(some_other_var)
 # Exception, "some_other_var" is not exported by the module
로그인 후 복사

这个属性可用于定义从模块导出哪些变量和函数。我们创建了一个Python模块…/some_module/单独文件(__init__.py)。在这个文件中定义了2个变量和一个函数,只导出其中的2个(func和some_var)。如果我们尝试在其他Python程序中导入some_module的内容,我们只能得到2个内容。

但是要注意,__all__变量只影响上面所示的* import,我们仍然可以使用显式的名称导入函数和变量,比如import some_other_var from some_module。

另一个常见的双下划线变量(模块属性)是__file__。这个变量标识了访问它的文件的路径:

 from pathlib import Path
 
 print(__file__)
 print(Path(__file__).resolve())
 # /home/.../directory/examples.py
 
 # Or the old way:
 import os
 print(os.path.dirname(os.path.abspath(__file__)))
 # /home/.../directory/
로그인 후 복사

这样我们就可以结合__all__和__file__,可以在一个文件夹中加载所有模块:

# Directory structure:
 # .
 # |____some_dir
 # |____module_three.py
 # |____module_two.py
 # |____module_one.py
 
 from pathlib import Path, PurePath
 modules = list(Path(__file__).parent.glob("*.py"))
 print([PurePath(f).stem for f in modules if f.is_file() and not f.name == "__init__.py"])
 # ['module_one', 'module_two', 'module_three']
로그인 후 복사

最后一个我重要的属性是的是__debug__。它可以用于调试,但更具体地说,它可以用于更好地控制断言:

 # example.py
 def func():
if __debug__:
print("debugging logs")
 
# Do stuff...
 
 func()
로그인 후 복사

如果我们使用python example.py正常运行这段代码,我们将看到打印出“调试日志”,但是如果我们使用python -O example.py,优化标志(-O)将把__debug__设置为false并删除调试消息。因此,如果在生产环境中使用-O运行代码,就不必担心调试过程中被遗忘的打印调用,因为它们都不会显示。

创建自己魔法方法?

我们可以创建自己的方法和属性吗?是的,你可以,但你不应该这么做。

双下划线名称是为Python语言的未来扩展保留的,不应该用于自己的代码。如果你决定在你的代码中使用这样的名称,那么将来如果它们被添加到Python解释器中,这就与你的代码不兼容了。所以对于这些方法,我们只要记住和使用就好了。

위 내용은 Python의 매직 메소드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

MySQL은 지불해야합니다 MySQL은 지불해야합니다 Apr 08, 2025 pm 05:36 PM

MySQL에는 무료 커뮤니티 버전과 유료 엔터프라이즈 버전이 있습니다. 커뮤니티 버전은 무료로 사용 및 수정할 수 있지만 지원은 제한되어 있으며 안정성이 낮은 응용 프로그램에 적합하며 기술 기능이 강합니다. Enterprise Edition은 안정적이고 신뢰할 수있는 고성능 데이터베이스가 필요하고 지원 비용을 기꺼이 지불하는 응용 프로그램에 대한 포괄적 인 상업적 지원을 제공합니다. 버전을 선택할 때 고려 된 요소에는 응용 프로그램 중요도, 예산 책정 및 기술 기술이 포함됩니다. 완벽한 옵션은없고 가장 적합한 옵션 만 있으므로 특정 상황에 따라 신중하게 선택해야합니다.

설치 후 MySQL을 사용하는 방법 설치 후 MySQL을 사용하는 방법 Apr 08, 2025 am 11:48 AM

이 기사는 MySQL 데이터베이스의 작동을 소개합니다. 먼저 MySQLworkBench 또는 명령 줄 클라이언트와 같은 MySQL 클라이언트를 설치해야합니다. 1. MySQL-Uroot-P 명령을 사용하여 서버에 연결하고 루트 계정 암호로 로그인하십시오. 2. CreateABase를 사용하여 데이터베이스를 작성하고 데이터베이스를 선택하십시오. 3. CreateTable을 사용하여 테이블을 만들고 필드 및 데이터 유형을 정의하십시오. 4. InsertInto를 사용하여 데이터를 삽입하고 데이터를 쿼리하고 업데이트를 통해 데이터를 업데이트하고 DELETE를 통해 데이터를 삭제하십시오. 이러한 단계를 마스터하고 일반적인 문제를 처리하는 법을 배우고 데이터베이스 성능을 최적화하면 MySQL을 효율적으로 사용할 수 있습니다.

고로드 애플리케이션의 MySQL 성능을 최적화하는 방법은 무엇입니까? 고로드 애플리케이션의 MySQL 성능을 최적화하는 방법은 무엇입니까? Apr 08, 2025 pm 06:03 PM

MySQL 데이터베이스 성능 최적화 안내서 리소스 집약적 응용 프로그램에서 MySQL 데이터베이스는 중요한 역할을 수행하며 대규모 트랜잭션 관리를 담당합니다. 그러나 응용 프로그램 규모가 확장됨에 따라 데이터베이스 성능 병목 현상은 종종 제약이됩니다. 이 기사는 일련의 효과적인 MySQL 성능 최적화 전략을 탐색하여 응용 프로그램이 고 부하에서 효율적이고 반응이 유지되도록합니다. 실제 사례를 결합하여 인덱싱, 쿼리 최적화, 데이터베이스 설계 및 캐싱과 같은 심층적 인 주요 기술을 설명합니다. 1. 데이터베이스 아키텍처 설계 및 최적화 된 데이터베이스 아키텍처는 MySQL 성능 최적화의 초석입니다. 몇 가지 핵심 원칙은 다음과 같습니다. 올바른 데이터 유형을 선택하고 요구 사항을 충족하는 가장 작은 데이터 유형을 선택하면 저장 공간을 절약 할 수있을뿐만 아니라 데이터 처리 속도를 향상시킬 수 있습니다.

hadidb : 파이썬의 가볍고 수평 확장 가능한 데이터베이스 hadidb : 파이썬의 가볍고 수평 확장 가능한 데이터베이스 Apr 08, 2025 pm 06:12 PM

HADIDB : 가볍고 높은 수준의 확장 가능한 Python 데이터베이스 HadIDB (HADIDB)는 파이썬으로 작성된 경량 데이터베이스이며 확장 수준이 높습니다. PIP 설치를 사용하여 HADIDB 설치 : PIPINSTALLHADIDB 사용자 관리 사용자 만들기 사용자 : createUser () 메소드를 작성하여 새 사용자를 만듭니다. Authentication () 메소드는 사용자의 신원을 인증합니다. Fromhadidb.operationimportuseruser_obj = user ( "admin", "admin") user_obj.

MongoDB 데이터베이스 비밀번호를 보는 Navicat의 방법 MongoDB 데이터베이스 비밀번호를 보는 Navicat의 방법 Apr 08, 2025 pm 09:39 PM

해시 값으로 저장되기 때문에 MongoDB 비밀번호를 Navicat을 통해 직접 보는 것은 불가능합니다. 분실 된 비밀번호 검색 방법 : 1. 비밀번호 재설정; 2. 구성 파일 확인 (해시 값이 포함될 수 있음); 3. 코드를 점검하십시오 (암호 하드 코드 메일).

MySQL은 인터넷이 필요합니까? MySQL은 인터넷이 필요합니까? Apr 08, 2025 pm 02:18 PM

MySQL은 기본 데이터 저장 및 관리를위한 네트워크 연결없이 실행할 수 있습니다. 그러나 다른 시스템과의 상호 작용, 원격 액세스 또는 복제 및 클러스터링과 같은 고급 기능을 사용하려면 네트워크 연결이 필요합니다. 또한 보안 측정 (예 : 방화벽), 성능 최적화 (올바른 네트워크 연결 선택) 및 데이터 백업은 인터넷에 연결하는 데 중요합니다.

MySQL Workbench가 Mariadb에 연결할 수 있습니다 MySQL Workbench가 Mariadb에 연결할 수 있습니다 Apr 08, 2025 pm 02:33 PM

MySQL Workbench는 구성이 올바른 경우 MariadB에 연결할 수 있습니다. 먼저 커넥터 유형으로 "mariadb"를 선택하십시오. 연결 구성에서 호스트, 포트, 사용자, 비밀번호 및 데이터베이스를 올바르게 설정하십시오. 연결을 테스트 할 때는 마리아드 브 서비스가 시작되었는지, 사용자 이름과 비밀번호가 올바른지, 포트 번호가 올바른지, 방화벽이 연결을 허용하는지 및 데이터베이스가 존재하는지 여부를 확인하십시오. 고급 사용에서 연결 풀링 기술을 사용하여 성능을 최적화하십시오. 일반적인 오류에는 불충분 한 권한, 네트워크 연결 문제 등이 포함됩니다. 오류를 디버깅 할 때 오류 정보를 신중하게 분석하고 디버깅 도구를 사용하십시오. 네트워크 구성을 최적화하면 성능이 향상 될 수 있습니다

MySQL에는 서버가 필요합니까? MySQL에는 서버가 필요합니까? Apr 08, 2025 pm 02:12 PM

생산 환경의 경우 성능, 신뢰성, 보안 및 확장 성을 포함한 이유로 서버는 일반적으로 MySQL을 실행해야합니다. 서버에는 일반적으로보다 강력한 하드웨어, 중복 구성 및 엄격한 보안 조치가 있습니다. 소규모 저하 애플리케이션의 경우 MySQL이 로컬 컴퓨터에서 실행할 수 있지만 자원 소비, 보안 위험 및 유지 보수 비용은 신중하게 고려되어야합니다. 신뢰성과 보안을 높이려면 MySQL을 클라우드 또는 기타 서버에 배포해야합니다. 적절한 서버 구성을 선택하려면 응용 프로그램 부하 및 데이터 볼륨을 기반으로 평가가 필요합니다.

See all articles