클래스 이미은 정의 된 하위 클래스를 등록합니다. 목록을 얻을 수있는 class.__subclasses__()
method 전화 :
>>> class Monster(object):
... pass
...
>>> class Lochness(Monster):
... pass
...
>>> class Yeti(Monster):
... pass
...
>>> Monster.__subclasses__()
[<class '__main__.Lochness'>, <class '__main__.Yeti'>]
.__subclasses__()
는 현재 살아 서브 클래스의 목록을 반환합니다. Yeti
(모듈의 del Yeti
에 대한 모든 참조를 지우려면 모든 인스턴스, 하위 클래스, 가져 오기 등을 삭제하십시오) .__subclasses__()
에 전화하면 더 이상 나열되지 않습니다. 본질적으로 .__subclasses__()
은 CPython implementation detail이지만이 방법은 새로운 스타일의 클래스 (2.2 이상, 3.x까지)를 지원하는 모든 Python 버전에 있습니다.
그렇지 않으면, 클래스 생성에 훅하는 표준 방법을 정의하는 것입니다 metaclass :
class MonstersMeta(type):
def __new__(metaclass, name, bases, namespace):
cls = super(MonstersMeta, metaclass).__new__(metaclass, name, bases, namespace)
if issubclass(cls, Monster) and not cls is Monster:
Monster.monsters.append(cls)
return cls
class Monster(object):
__metaclass__ = MonstersMeta
monsters = []
class Lochness(Monster):
pass
class Yeti(Monster):
pass
데모 :
def registered_monster(cls):
Monster.monsters.append(cls)
return cls
class Monster(object):
monsters = []
@registered_monster
class Lochness(Monster):
pass
@registered_monster
class Yeti(Monster):
pass
: 당신이 class decorator을 사용할 수 있습니다
>>> class Monster(object):
... __metaclass__ = MonstersMeta
... monsters = []
...
>>> class Lochness(Monster):
... pass
...
>>> class Yeti(Monster):
... pass
...
>>> Monster.monsters
[<class '__main__.Lochness'>, <class '__main__.Yeti'>]
또는 데모 :
>>> class Monster(object):
... monsters = []
...
>>> @registered_monster
... class Lochness(Monster):
... pass
...
>>> @registered_monster
... class Yeti(Monster):
... pass
...
>>> Monster.monsters
[<class '__main__.Lochness'>, <class '__main__.Yeti'>]
차이점은 몬스터를 등록하는 책임을지는 부분입니다. 기본은 MonstersMeta
유형이거나 명시 적으로 장식되어 있습니다.
어느 쪽이든, 메타 클래스 또는 클래스 데코레이터는 영구 참조를 등록합니다. 실제로 .__subclasses__()
동작을 에뮬레이트하려는 경우 weakref
module을 사용할 수 있습니다. 이 경우는 type.__subclasses__()
를 사용하는을위한 확실한 해결책에서 제외
굉장합니다. 나는 이런 것을 원한다고 생각했지만, 메타 클래스 사용법을 전혀 모르고있었습니다. – vmkrish