후레임의 프로그래밍
파이썬의 메타 클래스는 무엇입니까? 본문
질문
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
'스택오버플로우(Stack Overflow)' 카테고리의 다른 글
추적되었지만 현재 .gitignore에 있는 파일을 Git이 "잊게"만드는 방법은 무엇입니까? (0) | 2020.10.26 |
---|---|
파일이 예외없이 존재하는지 어떻게 확인합니까? (0) | 2020.10.26 |
"px", "dip", "dp"및 "sp"의 차이점은 무엇입니까? (0) | 2020.10.26 |
파이썬에 삼항 조건 연산자가 있습니까? (0) | 2020.10.26 |
JavaScript 개체에서 속성을 제거하려면 어떻게합니까? (0) | 2020.10.26 |