Python Language
메타 스케
수색…
소개
메타 클래스를 사용하면 새 클래스가 기본적으로 사용하는 type
메타 클래스를 대체하여 파이썬 클래스의 동작 (정의, 인스턴스화, 액세스 등의 측면에서)을 깊이 수정할 수 있습니다.
비고
아키텍처를 설계 할 때, 메타 클래스로 수행 할 수있는 많은 것들이보다 간단한 의미를 사용하여 수행 될 수 있다고 생각하십시오 :
- 전통적인 상속은 종종 충분하다.
- 클래스 데코레이터는 기능을 클래스에 임시로 결합 할 수 있습니다.
- Python 3.6은
__init_subclass__()
를 도입하여 클래스가 서브 클래스 생성에 참여하도록합니다.
기본 메타 클래스
type
이 3 개의 인자로 호출 될 때 그것은 (메타) 클래스처럼 행동하고 새로운 인스턴스를 생성한다. 새로운 클래스 / 유형을 생성합니다.
Dummy = type('OtherDummy', (), dict(x=1))
Dummy.__class__ # <type 'type'>
Dummy().__class__.__class__ # <type 'type'>
type
을 서브 클래스 화하여 사용자 정의 메타 클래스를 작성할 수 있습니다.
class mytype(type):
def __init__(cls, name, bases, dict):
# call the base initializer
type.__init__(cls, name, bases, dict)
# perform custom initialization...
cls.__custom_attribute__ = 2
이제 type
과 같은 방식으로 클래스를 만드는 데 사용할 수있는 새로운 맞춤형 mytype
메타 클래스가 mytype
.
MyDummy = mytype('MyDummy', (), dict(x=2))
MyDummy.__class__ # <class '__main__.mytype'>
MyDummy().__class__.__class__ # <class '__main__.mytype'>
MyDummy.__custom_attribute__ # 2
class
키워드를 사용하여 새 클래스를 만들면 metaclass가 기본적으로 baseclasses를 기반으로 선택됩니다.
>>> class Foo(object):
... pass
>>> type(Foo)
type
위 예제에서 유일한 기본 클래스는 object
이므로 메타 클래스는 유형의 object
type
입니다. 파이썬 2와 파이썬 3 중 어느 것을 사용 하느냐에 따라 다르지만, 기본값을 오버라이드 할 수 있습니다 :
__metaclass__
라는 특수 클래스 수준 속성을 사용하여 메타 클래스를 지정할 수 있습니다.
class MyDummy(object):
__metaclass__ = mytype
type(MyDummy) # <class '__main__.mytype'>
특수한 metaclass
키워드 인수는 메타 클래스를 지정합니다.
class MyDummy(metaclass=mytype):
pass
type(MyDummy) # <class '__main__.mytype'>
클래스 선언에있는 모든 키워드 인수 ( metaclass
제외)는 metaclass
클래스로 전달됩니다. 따라서 class MyDummy(metaclass=mytype, x=2)
는 키워드 인수로 x=2
를 mytype
생성자에 전달합니다.
자세한 내용은 파이썬 메타 클래스에 대한 자세한 설명을 읽으십시오.
메타 클래스를 사용하는 싱글 톤
싱글 톤은 클래스의 인스턴스화를 하나의 인스턴스 / 객체로 제한하는 패턴입니다. python 단독 디자인 패턴에 대한 자세한 내용은 여기를 참조 하십시오 .
class SingletonType(type):
def __call__(cls, *args, **kwargs):
try:
return cls.__instance
except AttributeError:
cls.__instance = super(SingletonType, cls).__call__(*args, **kwargs)
return cls.__instance
class MySingleton(object):
__metaclass__ = SingletonType
class MySingleton(metaclass=SingletonType):
pass
MySingleton() is MySingleton() # True, only one instantiation occurs
메타 클래스 사용하기
메타 클래스 구문
class MyClass(object):
__metaclass__ = SomeMetaclass
class MyClass(metaclass=SomeMetaclass):
pass
Python 2 및 3과 six
호환성
import six
class MyClass(six.with_metaclass(SomeMetaclass)):
pass
메타 클래스를 사용한 사용자 지정 기능
클래스가 빌드 될 때마다 문자열이 표준 출력에 인쇄되거나 예외가 throw되도록 메타 클래스의 기능을 변경할 수 있습니다. 이 메타 클래스는 빌드되는 클래스의 이름을 인쇄합니다.
class VerboseMetaclass(type):
def __new__(cls, class_name, class_parents, class_dict):
print("Creating class ", class_name)
new_class = super().__new__(cls, class_name, class_parents, class_dict)
return new_class
다음과 같이 메타 클래스를 사용할 수 있습니다.
class Spam(metaclass=VerboseMetaclass):
def eggs(self):
print("[insert example string here]")
s = Spam()
s.eggs()
표준 출력은 다음과 같습니다.
Creating class Spam
[insert example string here]
메타 클래스 소개
메타 클래스 란 무엇입니까?
파이썬에서는 모든 것이 객체입니다 : 정수, 문자열,리스트, 심지어 함수와 클래스 자체가 객체입니다. 그리고 모든 객체는 클래스의 인스턴스입니다.
객체 x의 클래스를 확인하려면 type(x)
호출 할 수 있습니다.
>>> type(5)
<type 'int'>
>>> type(str)
<type 'type'>
>>> type([1, 2, 3])
<type 'list'>
>>> class C(object):
... pass
...
>>> type(C)
<type 'type'>
파이썬에서 대부분의 클래스는 type
인스턴스입니다. type
자체도 클래스입니다. 인스턴스가 클래스이기도 한 이러한 클래스를 메타 클래스라고합니다.
가장 단순한 메타 클래스
: OK, 그래서 파이썬에서 하나의 메타 클래스 이미있는 type
. 다른 것을 만들 수 있습니까?
class SimplestMetaclass(type):
pass
class MyClass(object):
__metaclass__ = SimplestMetaclass
그것은 어떤 기능도 추가하지 않지만 새로운 메타 클래스입니다. MyClass는 이제 SimplestMetaclass의 인스턴스입니다.
>>> type(MyClass)
<class '__main__.SimplestMetaclass'>
무언가를하는 Metaclass
클래스를 생성하는 원래 __new__
를 호출하기 전에, 무언가를하는 메타 클래스는 일반적으로 type
의 __new__
오버라이드하여 생성 될 클래스의 일부 속성을 수정합니다.
class AnotherMetaclass(type):
def __new__(cls, name, parents, dct):
# cls is this class
# name is the name of the class to be created
# parents is the list of the class's parent classes
# dct is the list of class's attributes (methods, static variables)
# here all of the attributes can be modified before creating the class, e.g.
dct['x'] = 8 # now the class will have a static variable x = 8
# return value is the new class. super will take care of that
return super(AnotherMetaclass, cls).__new__(cls, name, parents, dct)
기본 메타 클래스
파이썬의 모든 것이 객체라는 것을 들었을 것입니다. 사실이며 모든 객체에는 클래스가 있습니다.
>>> type(1)
int
리터럴 1은 int
의 인스턴스입니다. 클래스를 선언 할 수 있습니다.
>>> class Foo(object):
... pass
...
이제 인스턴스화 할 수 있습니다.
>>> bar = Foo()
bar
의 종류는 무엇입니까?
>>> type(bar)
Foo
좋은, bar
는 Foo
의 인스턴스입니다. 그러나 Foo
클래스의 클래스는 무엇입니까?
>>> type(Foo)
type
좋아, Foo
자체가 type
의 인스턴스입니다. type
자체는 어떻습니까?
>>> type(type)
type
그렇다면 메타 클래스 란 무엇입니까? 지금은 그것이 클래스의 클래스에 대한 멋진 이름 인 것처럼 가장 할 수 있습니다. 테이크 아웃 :
- 모든 것이 파이썬에서 객체이기 때문에 모든 것이 클래스를가집니다.
- 클래스의 클래스를 메타 클래스라고합니다.
- 기본 메타 클래스는
type
이며, 지금까지 가장 일반적인 메타 클래스입니다.
그런데 왜 메타 클래스에 대해 알아야합니까? 음, Python 자체는 상당히 "해킹 가능"하며 메타 프로그래밍과 같은 고급 기능을 수행하거나 클래스를 초기화하는 방법을 제어하려는 경우 메타 클래스의 개념이 중요합니다.