Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

후레임의 프로그래밍

파이썬의 메타 클래스는 무엇입니까? 본문

스택오버플로우(Stack Overflow)

파이썬의 메타 클래스는 무엇입니까?

후레임 2020. 10. 26. 13:23
질문

 

Python에서 메타 클래스 란 무엇이며 무엇을 위해 사용합니까?





답변

메타 클래스는 클래스의 클래스입니다. 클래스는 클래스의 인스턴스 (즉, 객체)가 동작하는 방식을 정의하는 반면 메타 클래스는 클래스가 동작하는 방식을 정의합니다. 클래스는 메타 클래스의 인스턴스입니다.

Python에서는 메타 클래스에 대해 임의의 콜 러블을 사용할 수 있습니다 (예 : Jerub쇼) 더 나은 접근 방식은 실제 클래스 자체로 만드는 것입니다. type은 Python의 일반적인 메타 클래스입니다. type은 그 자체가 클래스이고 자체 유형입니다. 순수하게 파이썬에서 type과 같은 것을 다시 만들 수는 없지만 파이썬은 약간 속임수를 쓰게됩니다. Python에서 자신 만의 메타 클래스를 만들려면 type을 하위 클래스로 만들기 만하면됩니다.

메타 클래스는 클래스 팩토리로 가장 일반적으로 사용됩니다. 클래스를 호출하여 객체를 생성 할 때 Python은 메타 클래스를 호출하여 새 클래스를 생성합니다 ( 'class'문을 실행할 때). 따라서 일반 __ init ____ new __메서드와 결합 된 메타 클래스를 사용하면 클래스를 만들 때 일부 레지스트리에 새 클래스를 등록하거나 클래스를 교체하는 등 '추가 작업'을 수행 할 수 있습니다. 완전히 다른 것입니다.

class문이 실행되면 Python은 먼저 class문의 본문을 일반 코드 블록으로 실행합니다. 결과 네임 스페이스 (dict)는 클래스가 될 클래스의 속성을 보유합니다. 메타 클래스는 클래스가 될 클래스 (메타 클래스가 상 속됨)의 기본 클래스, 대상 클래스 (있는 경우)의 __ metaclass __속성 또는 __ metaclass__를보고 결정됩니다.전역 변수. 그런 다음 메타 클래스를 인스턴스화하기 위해 클래스의 이름,베이스 및 속성과 함께 호출됩니다.

하지만 메타 클래스는 실제로 클래스의 유형을 정의하는 것이 아니라 팩토리 만 정의하므로 더 많은 작업을 수행 할 수 있습니다. 예를 들어 메타 클래스에서 일반 메서드를 정의 할 수 있습니다. 이러한 메타 클래스 메서드는 인스턴스없이 클래스에서 호출 할 수 있다는 점에서 클래스 메서드와 비슷하지만 클래스의 인스턴스에서 호출 할 수 없다는 점에서 클래스 메서드와도 다릅니다. type .__ subclasses __ ()type메타 클래스에 대한 메서드의 예입니다. 또한 __ add __, __ iter ____ getattr __와 같은 일반적인 '마법'메서드를 정의하여 클래스 동작 방식을 구현하거나 변경할 수 있습니다.

다음은 비트와 조각의 집계 된 예입니다.

def make_hook(f):
    """Decorator to turn 'foo' method into '__foo__'"""
        f.is_hook = 1
            return f
            
            class MyType(type):
                def __new__(mcls, name, bases, attrs):
                
                        if name.startswith('None'):
                                    return None
                                    
                                            # Go over attributes and see if they should be renamed.
                                                    newattrs = {}
                                                            for attrname, attrvalue in attrs.iteritems():
                                                                        if getattr(attrvalue, 'is_hook', 0):
                                                                                        newattrs['__%s__' % attrname] = attrvalue
                                                                                                    else:
                                                                                                                    newattrs[attrname] = attrvalue
                                                                                                                    
                                                                                                                            return super(MyType, mcls).__new__(mcls, name, bases, newattrs)
                                                                                                                            
                                                                                                                                def __init__(self, name, bases, attrs):
                                                                                                                                        super(MyType, self).__init__(name, bases, attrs)
                                                                                                                                        
                                                                                                                                                # classregistry.register(self, self.interfaces)
                                                                                                                                                        print "Would register class %s now." % self
                                                                                                                                                        
                                                                                                                                                            def __add__(self, other):
                                                                                                                                                                    class AutoClass(self, other):
                                                                                                                                                                                pass
                                                                                                                                                                                        return AutoClass
                                                                                                                                                                                                # Alternatively, to autogenerate the classname as well as the class:
                                                                                                                                                                                                        # return type(self.__name__ + other.__name__, (self, other), {})
                                                                                                                                                                                                        
                                                                                                                                                                                                            def unregister(self):
                                                                                                                                                                                                                    # classregistry.unregister(self)
                                                                                                                                                                                                                            print "Would unregister class %s now." % self
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            class MyObject:
                                                                                                                                                                                                                                __metaclass__ = MyType
                                                                                                                                                                                                                                
                                                                                                                                                                                                                                
                                                                                                                                                                                                                                class NoneSample(MyObject):
                                                                                                                                                                                                                                    pass
                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                    # Will print "NoneType None"
                                                                                                                                                                                                                                    print type(NoneSample), repr(NoneSample)
                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                    class Example(MyObject):
                                                                                                                                                                                                                                        def __init__(self, value):
                                                                                                                                                                                                                                                self.value = value
                                                                                                                                                                                                                                                    @make_hook
                                                                                                                                                                                                                                                    def add(self, other):
                                                                                                                                                                                                                                                            return self.__class__(self.value + other.value)
                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                            # Will unregister the class
                                                                                                                                                                                                                                                            Example.unregister()
                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                            inst = Example(10)
                                                                                                                                                                                                                                                            # Will fail with an AttributeError
                                                                                                                                                                                                                                                            #inst.unregister()
                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                            print inst + inst
                                                                                                                                                                                                                                                            class Sibling(MyObject):
                                                                                                                                                                                                                                                                pass
                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                ExampleSibling = Example + Sibling
                                                                                                                                                                                                                                                                # ExampleSibling is now a subclass of both Example and Sibling (with no
                                                                                                                                                                                                                                                                # content of its own) although it will believe it's called 'AutoClass'
                                                                                                                                                                                                                                                                print ExampleSibling
                                                                                                                                                                                                                                                                print ExampleSibling.__mro__
                                                                                                                                                                                                                                                                



출처 : https://stackoverflow.com/questions/100003