수색…


소개

메타 클래스를 사용하면 새 클래스가 기본적으로 사용하는 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 중 어느 것을 사용 하느냐에 따라 다르지만, 기본값을 오버라이드 할 수 있습니다 :

Python 2.x 2.7

__metaclass__ 라는 특수 클래스 수준 속성을 사용하여 메타 클래스를 지정할 수 있습니다.

class MyDummy(object):
    __metaclass__ = mytype
type(MyDummy)  # <class '__main__.mytype'>
Python 3.x 3.0

특수한 metaclass 키워드 인수는 메타 클래스를 지정합니다.

class MyDummy(metaclass=mytype):
    pass
type(MyDummy)  # <class '__main__.mytype'>

클래스 선언에있는 모든 키워드 인수 ( metaclass 제외)는 metaclass 클래스로 전달됩니다. 따라서 class MyDummy(metaclass=mytype, x=2) 는 키워드 인수로 x=2mytype 생성자에 전달합니다.

자세한 내용은 파이썬 메타 클래스에 대한 자세한 설명을 읽으십시오.

메타 클래스를 사용하는 싱글 톤

싱글 톤은 클래스의 인스턴스화를 하나의 인스턴스 / 객체로 제한하는 패턴입니다. 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
Python 2.x 2.7
class MySingleton(object):
    __metaclass__ = SingletonType
Python 3.x 3.0
class MySingleton(metaclass=SingletonType):
    pass
MySingleton() is MySingleton()  # True, only one instantiation occurs

메타 클래스 사용하기

메타 클래스 구문

Python 2.x 2.7
class MyClass(object):
    __metaclass__ = SomeMetaclass
Python 3.x 3.0
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

좋은, barFoo 의 인스턴스입니다. 그러나 Foo 클래스의 클래스는 무엇입니까?

>>> type(Foo)
type

좋아, Foo 자체가 type 의 인스턴스입니다. type 자체는 어떻습니까?

>>> type(type)
type

그렇다면 메타 클래스 란 무엇입니까? 지금은 그것이 클래스의 클래스에 대한 멋진 이름 인 것처럼 가장 할 수 있습니다. 테이크 아웃 :

  • 모든 것이 파이썬에서 객체이기 때문에 모든 것이 클래스를가집니다.
  • 클래스의 클래스를 메타 클래스라고합니다.
  • 기본 메타 클래스는 type 이며, 지금까지 가장 일반적인 메타 클래스입니다.

그런데 왜 메타 클래스에 대해 알아야합니까? 음, Python 자체는 상당히 "해킹 가능"하며 메타 프로그래밍과 같은 고급 기능을 수행하거나 클래스를 초기화하는 방법을 제어하려는 경우 메타 클래스의 개념이 중요합니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow