클래스가 하위 분류될 때 코드를 실행하는 방법은 무엇입니까?
제 수업이 하위 분류될 때 코드를 트리거할 수 있는 방법이 있습니까?
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
예상대로 작동하지 않습니다.
먼저, 우리는 메타 클래스에 이 특정 메서드가 하위 클래스 동작에 대해 특별하게 호출되어야 한다는 것을 알리는 방법을 가지고 싶습니다. 우리는 단지 호출하고 싶은 함수에 속성을 설정할 것입니다.편의를 위해, 우리는 그 기능을 심지어 하나로 바꿀 것입니다.classmethod
그래서 그것이 발견된 진짜 기본 클래스도 발견될 수 있습니다.가장 편리한 데코레이터로 사용할 수 있도록 클래스 메소드를 반납하겠습니다.
import types
import inspect
def subclass_hook(func):
func.is_subclass_hook = True
return classmethod(func)
우리는 또한 편리한 방법을 원할 것입니다.subclass_hook
데코레이터가 사용되었습니다.우리는 알고 있습니다.classmethod
사용되었으니 확인하고 그 다음에 찾아보겠습니다.is_subclass_hook
기여하다.
def test_subclass_hook(thing):
x = (isinstance(thing, types.MethodType) and
getattr(thing.im_func, 'is_subclass_hook', False))
return x
마지막으로, 정보에 따라 작동하는 메타 클래스가 필요합니다.대부분의 경우 여기서 가장 흥미로운 작업은 제공된 각 베이스에서 후크를 확인하는 것입니다.그런 식으로, 슈퍼는 가장 놀라운 방식으로 작동합니다.
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)
그리고 그것으로 충분합니다.
>>> 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
'sourcecode' 카테고리의 다른 글
openxml 스프레드쉬트 다른 이름으로 저장 (0) | 2023.07.18 |
---|---|
탭을 사용하지 않고 주피터 노트북에서 자동 완성하는 방법은 무엇입니까? (0) | 2023.07.18 |
세션 상태가 세션 ID를 생성했지만 응답이 응용 프로그램에 의해 이미 플러시되었기 때문에 저장할 수 없습니다."를 발생시키는 원인 (0) | 2023.07.18 |
동일한 라인으로 출력하여 이전 출력을 덮어쓰시겠습니까? (0) | 2023.07.18 |
잭슨 연속화 시 속성을 동적으로 무시하는 방법 (0) | 2023.07.18 |