2012-09-29 2 views
1

나는 ZODB에서 영속화 된 많은 클래스를 가지고있다. 모든 클래스는 일부 인덱싱 기능을 공유해야하지만 그 중 모두가 많은 속성을 정의합니다. 등록 정보는 설명자를 사용하여 클래스 수준에서 정의되며 유효성 검사를 위해 쓰기를 가로 채고 DB에서 중복을 확인할 수 있습니다. 이를 위해 모든 클래스에는 자동으로 유지 관리되는 속성 목록 인 _properties이 있습니다. 그들은 또한 _indices과 몇 가지 다른 기능을 보유하고 있습니다.이 기능은 모든 단일 요소 클래스 (약 10 개 정도)에 직접 복사하지 않으려합니다. 그것이 무엇을해야생성시 클래스에 속성 첨부하기

class BaseElement(object): 
    _properties = None 

class ElementFlavour1(BaseElement): 
    _properties = 'a', 'b', 'c' 

.... 

class ElementFlavourN(BaseElement): 
    _properties = 'e', 'f', 'g' 

for item in locals(): 
    if issubclass(item, BaseElement): 
     item._v_properties_set = set(item._properties) if item._properties else set() 

그래서, 기본적으로 않습니다 :

는 다음과 같은 코드를 생각해 내가 선형 _properties을 반복 할 필요가 있지만, 일부 속성이 존재하는 경우 또한, 빠른 검색을 수행 할 수업. 그럼에도 불구하고 나는 반복해서 자신의 취향에 따라 BaseElement을 명시하고 싶지 않습니다.

현재 솔루션이 작동하지만 추악한 해킹으로 간주하여 제거하고 싶습니다. 예 : 다른 모듈에있는 BaseElement의 서브 클래스는 해당 속성을 올바르게 설정하지 못합니다. __new__을 가지고 노는 것은 클래스 구성을 가로채는 것이 아니라 인스턴스화를 가로막는 잘못된 방법으로 보입니다. 그럼 어떻게 제대로 할 수 있을까요?

P. 나는 OrderedDict에 대해 알고 있지만 이것은 내가 찾고있는 것이 아니다. 깨끗한 방법으로 클래스 생성 프로세스에 연결하고 거기에 임의의 기능을 추가하고 싶습니다. 또한 클래스 장식이 할 수

class BaseType(type): 
    def __init__(cls, name, bases, clsdict): 
     super(BaseType, cls).__init__(name, bases, clsdict) 
     setattr(cls,'_v_properties_set', 
       set(cls._properties) if cls._properties else set()) 

class BaseElement(object): 
    __metaclass__ = BaseType  
    _properties = None 

class ElementFlavour1(BaseElement): 
    _properties = 'a', 'b', 'c' 

class ElementFlavourN(BaseElement): 
    _properties = 'e', 'f', 'g' 

print(ElementFlavourN._v_properties_set) 
# set(['e', 'g', 'f']) 

,하지만 당신은 개별적으로 BaseElement 대한 각각의 서브 클래스를 장식해야 할 것 :

+1

도움이 될 수 있습니다. http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python – Blender

답변

4

당신은 메타 클래스와 함께이 작업을 수행 할 수 있습니다. 메타 클래스는 상속되므로 한 번 정의하면됩니다.

+0

정확히 내가 필요한 것, 감사합니다! 블렌더 링크 덕분에, 마침내 그 마법에 대해 이해하게되었습니다. – Michael

관련 문제