2016-09-12 2 views
6

나는 기본적으로 통신 프로토콜의 일부를 열거를 나타냅니다 파이썬에서 자동으로 생성 된 클래스의 많은 양을 가지고, 그들은이 방법은 또한 자동 발전기 및 것이 쉽게 그래서서브 클래스 파이썬에 클래스 변수를 동적으로 추가 할 수 있습니까?

# definitions.py 

class StatusCodes(ParamEnum): 
    Success = 1 
    Error = 2 
    UnexpectedAlpaca = 3 

class AlpacaType(ParamEnum): 
    Fuzzy = 0 
    ReallyMean = 1 

# etc etc etc 

일을 정의처럼 인간이 수정할 수 있습니다. ParamEnum 클래스는 들어오는 네트워크 데이터 등으로부터 모든 기능, get/setting, 비교, 변환 및 생성을 제공합니다. 그러나 이러한 클래스에는 몇 가지 추가 메타 데이터가 필요합니다. 나는 은 덜 읽을 수로,하지만 각 클래스의 소스 정의에이를 추가하지 않으 내가 그러나이

# param_enum.py 

class ParamEnum(object): 
    def __init__(self): 
     self.__class__._metadata = get_class_metadata(self.__class__) 

처럼 그 일을하고있는 순간에 autogenerator

을 깰 것 (메타 데이터는 변경되지 않으므로 한 번만 설정하면됩니다)

I (예 : 메타 데이터가 변경되지 않기 때문에 자주 발생하는) 이러한 열거 형 중 하나를 인스턴스화 할 때마다 발생하므로 다소 비효율적 인 것으로 나타납니다. 이것을 정의 파일의 맨 아래에 추가하려고 시도했지만 문제가 발생했습니다. 거기도.

class StatusCodes(ParamEnum): 
    Success = 1 
    Error = 2 
    UnexpectedAlpaca = 3 

for var in locals(): # or globals? 
    add_metadata(var) 
    #doesn't work because it is in the same file, modifying dict while iteratng 

서브 클래스에 상속 될 수 있습니다/재정 클래스를 정의 할 때에 기능을 추가 파이썬에서 방법이 있나요? 클래스 또는 함수의 수정이 후 : 이상적으로는 클래스 장식

def add_metadata(cls): 
    cls._metadata = get_class_metadata(cls) 
    return cls 

@add_metadata 
class StatusCodes(ParamEnum): 
    Success = 1 
    Error = 2 
    UnexpectedAlpaca = 3 

장식을 가지고있는 매우 동기가 실제로 무엇을하고 싶은 것입니다을 사용

class ParamEnum(object): 
    def __when_class_defined__(cls): 
     add_metadata(cls) 
+1

클래스에서 클래스는 해당 Metaclass의 인스턴스입니다. 즉, ParamEnum에 '__new__'을 무시한 Metaclass를 부여하면됩니다. – Phillip

답변

5

같은 것을하고 싶습니다 생성되었습니다.

장식가에 익숙하지 않은 경우 this (다소 길지만)을 읽어보십시오.

메타 클래스를 사용할 수도 있지만 데코레이터보다 복잡합니다. 추가 장식 라인 @add_metadata을 피하고 지정된 하위 클래스 ParamEnum에 대해 중복되는 것으로 생각되는 경우 ParamEnum 내에서 지연 평가를 사용하여 _metadataa descriptor을 지연 생성 할 수 있습니다.

class MetadataDescriptor(object): 
    def __get__(self, obj, cls): 
     if cls._metadata_value is None: 
      cls._metadata_value = get_class_metadata(cls) 
     return cls._metadata_value 

class ParamEnum(object): 
    _metadata_value = None 
    _metadata = MetadataDescriptor() 
+0

나는 descriptor가 장식 자보다 낫다고 생각한다. –

+0

@AlbertLee 나는 그 기술자가 더 우아하다고 생각한다. 그러나 이들은 코드를 누가 유지하는지에 따라 장애물이 될 수있는 상당히 진보 된 "마법"입니다. –

+0

설명자를 사용하여 매우 잘 작동하고 자동 생성 된 파일을 깨끗하게 유지합니다. 감사! –

관련 문제