2014-02-13 2 views
1

클래스가 다른 클래스에 의해 확장 될 때 Python에서 일부 코드를 실행하는 방법이 있습니까? 좀 더 정확히 말하면, 기본 클래스를 확장하는 모든 클래스의 레지스터를 자동으로 보관하고 싶습니다. 따라서, 나는 같은 것을 쓰고 싶습니다 코드의이 조각 한Python에서 클래스를 확장 할 때 코드 실행

class Base: 

    subclasses = {} 

    @classmethod 
    def extending(cls, subclass): 
     cls.subclasses[subclass.__name__] = subclass 

class Extend1(Base): 
    pass 

class Extend2(Base): 
    pass 

을, 나는 Base.subclasses는 두 개의 확장 클래스에 대한 링크가 포함되어 기대.

이 방법을 제안 해 줄 수 있습니까? 아니면, 아마도 동급 솔루션을 제공할까요?

답변

3

이것은 분명히 메타 클래스 용 응용 프로그램입니다. 즉, 클래스 C의 동작을 변경하려면 메타 클래스 인 C 자체의 클래스를 변경해야합니다 (보통 type).

class Meta(type): 
    def __new__(cls, clsname, bases, dct): 
     res = type.__new__(cls, clsname, bases, dct) 
     for cls in bases: 
      if isinstance(cls, Meta): 
       try: 
        cls.extending(res) 
       except AttributeError: 
        pass 
     return res 

I 클래스의 생성 차단 메타 클래스 있도록 type 상속베이스 _subclass 속성에 상기 생성 된 클래스를 기억하고있어 여기 용액 스터브이다. 그런 다음

class Base(object): 
    __metaclass__ = Meta 

    subclasses = {} 

    @classmethod 
    def extending(cls, subclass): 
     cls.subclasses[subclass.__name__] = subclass 

class Extend1(Base): 
    pass 

class Extend2(Base): 
    pass 

그런

>>> Base.subclasses 
{'Extend1': __main__.Extend1, 'Extend2': __main__.Extend2} 

매우 중요한 포인트 : 메타 클래스는 (나는이 정확히 적절한 용어 여기 아니라고 생각) inherited이다. 따라서 Extend1Extend2Meta의도 인스턴스 :

>>> type(Extend1) 
<class '__main__.Meta'> 
2

을 실제로 당신이 서브 클래스에만 관심이 있다면, 파이썬은 자동으로 당신에게 그것을 제공 할 수 있습니다. 모든 새로운 스타일 클래스에는 그 클래스의 직접적인 자손을 모두 돌려주는 __subclasses__() 메쏘드가 있습니다.

>>> class Base(object): 
...  pass 
... 
>>> class Child(Base): 
...  pass 
... 
>>> Base.__subclasses__() 
[<class '__main__.Child'>] 
>>> 
관련 문제