클래스가 서브 클래 싱 될 때 코드를 실행하는 방법은 무엇입니까? [복제]
이 질문에 이미 답변이 있습니다.
- 파이썬의 메타 클래스는 무엇입니까? 16 답변
내 클래스가 서브 클래 싱 될 때 코드를 트리거하는 방법이 있습니까?
class SuperClass:
def triggered_routine(subclass):
print("was subclassed by " + subclass.__name__)
magically_register_triggered_routine()
print("foo")
class SubClass0(SuperClass):
pass
print("bar")
class SubClass1(SuperClass):
print("test")
출력해야 함
foo
was subclassed by SubClass0
bar
test
was subclassed by SubClass1
클래스 (기본적으로)는 type
. 클래스의 인스턴스가있는 것처럼 Foo
의해 생성 foo = Foo(...)
의 인스턴스 type
(즉, 클래스)에 의해 생성된다 myclass = type(name, bases, clsdict)
.
클래스 생성 순간에 특별한 일이 일어나기를 원한다면, 클래스를 생성하는 것을 수정해야합니다 type
. 이를 수행하는 방법은 하위 클래스, type
즉 메타 클래스를 정의하는 것 입니다.
메타 클래스는 클래스와 인스턴스에 대한 클래스입니다.
Python2에서는 다음을 사용하여 클래스의 메타 클래스를 정의합니다.
class SuperClass:
__metaclass__ = Watcher
Watcher
의 하위 클래스는 어디에 있습니까 type
?
Python3에서는 구문이 다음과 같이 변경되었습니다.
class SuperClass(metaclass=Watcher)
둘 다 다음과 같습니다.
Superclass = Watcher(name, bases, clsdict)
여기서,이 경우에는 name
문자열과 동일 'Superclass'
하고, bases
튜플이다 (object, )
. 는 clsdict
클래스 정의의 본문에 정의 된 클래스 속성의 사전입니다.
에 유사성을합니다 myclass = type(name, bases, clsdict)
.
따라서 __init__
인스턴스 생성 순간에 이벤트를 제어 하기 위해 클래스를 사용하는 것처럼 메타 클래스의 __init__
다음을 사용하여 클래스 생성 순간에 이벤트를 제어 할 수 있습니다 .
class Watcher(type):
def __init__(cls, name, bases, clsdict):
if len(cls.mro()) > 2:
print("was subclassed by " + name)
super(Watcher, cls).__init__(name, bases, clsdict)
class SuperClass:
__metaclass__ = Watcher
print("foo")
class SubClass0(SuperClass):
pass
print("bar")
class SubClass1(SuperClass):
print("test")
인쇄물
foo
was subclassed by SubClass0
bar
test
was subclassed by SubClass1
편집 : 내 이전 게시물이 실제로 작동하지 않았습니다. 에서 서브 클래 싱 classmethod
이 예상대로 작동하지 않습니다.
First, we would like to have some way to tell the metaclass that this particular method is supposed to have the special called on subclass behavior, we'll just set an attribute on the function we'd like to call. As a convenience, we'll even turn the function into a classmethod
so that the real baseclass it was found in can be discovered, too. We'll return the classmethod so that it can be used as a decorator, which is most convenient.
import types
import inspect
def subclass_hook(func):
func.is_subclass_hook = True
return classmethod(func)
We're also going to want a convenient way to see that the subclass_hook
decorator was used. We know that classmethod
has been used, so we'll check for that, and only then look for the is_subclass_hook
attribute.
def test_subclass_hook(thing):
x = (isinstance(thing, types.MethodType) and
getattr(thing.im_func, 'is_subclass_hook', False))
return x
Finally, we need a metaclass that acts on the information: For most cases, the most interesting thing to do here is just check each of the supplied bases for hooks. In that way, super works in the least surprising way.
class MyMetaclass(type):
def __init__(cls, name, bases, attrs):
super(MyMetaclass, cls).__init__(name, bases, attrs)
for base in bases:
if base is object:
continue
for name, hook in inspect.getmembers(base, test_subclass_hook):
hook(cls)
and that should do it.
>>> class SuperClass:
... __metaclass__ = MyMetaclass
... @subclass_hook
... def triggered_routine(cls, subclass):
... print(cls.__name__ + " was subclassed by " + subclass.__name__)
>>> class SubClass0(SuperClass):
... pass
SuperClass was subclassed by SubClass0
>>> class SubClass1(SuperClass):
... print("test")
test
SuperClass was subclassed by SubClass1
참고URL : https://stackoverflow.com/questions/18126552/how-to-run-code-when-a-class-is-subclassed
'programing tip' 카테고리의 다른 글
iPhone 앱에 Python 포함 (0) | 2020.09.02 |
---|---|
조각 또는 활동에 도구 모음이있는 코디네이터 레이아웃 (0) | 2020.09.02 |
CORS Origin 헤더와 CSRF 토큰을 사용한 CSRF 보호 (0) | 2020.09.02 |
시뮬레이터의 Xcode 오류 :이 플랫폼에서는 MGIsDeviceOneOfType이 지원되지 않습니다. (0) | 2020.09.02 |
Android NFC 전화가 NFC 태그 역할을 할 수 있습니까? (0) | 2020.09.02 |