2016-09-12 5 views
6

私は基本的に、通信プロトコルの一部に列挙型を表すPythonで自動生成されたクラスの大規模な量を持って、彼らはこの方法でも、自動発電機とのために、それが容易になりますので、サブクラスのPythonにクラス変数を動的に追加できますか?

# definitions.py 

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

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

# etc etc etc 

物事を定義するように見えます人間が修正すること。 ParamEnumクラスは、着信ネットワークデータなどからすべての機能、取得/設定、比較、変換、作成を提供します。

ただし、これらのクラスはいくつかの追加のメタデータを必要とします。私はは、それが読みにくくなりますように、しかし、各クラスのソース定義にこれを追加したくないと私はしかし、この

# param_enum.py 

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

ようにそれをやっている瞬間に自動発生

を中断します(メタデータは変更されないので、一度だけ設定する必要があります)

私は、これらの列挙型のうちの1つをインスタンス化するたびに発生するため、多少非効率的ですこれを定義ファイルの最後に追加しようとしましたが、問題に遭遇しましたそこにも。

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 

サブクラスに継承できるクラスが定義されている場合に機能を追加/上書きのPythonでの方法は、ありますか?それが持っているクラスや関数の修正後:理想的には私は何がやりたいことは、実際にデコレータを持っていることは非常にモチベーションです

class ParamEnum(object): 
    def __when_class_defined__(cls): 
     add_metadata(cls) 
のようなもの
+1

クラスでは、クラスがそのメタクラスのインスタンスです。つまり、ParamEnumに '__new__'をオーバーライドしたメタクラスを与えることで、これを実現できます。 – Phillip

答えて

5

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

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

クラスのデコレータを使用したいと思います作成されました。

デコレータについてよくわからない場合は、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

私はデスクリプタがデコレータより優れていると思います。 –

+0

@AlbertLee私はあまりにも、記述子がよりエレガントだと思います。しかし、彼らは誰がコードを管理しているかによって障害になる可能性があるかなり高度な「魔法」です。 –

+0

ディスクリプタを使い、かなりうまく動作し、自動生成されたファイルをきれいに保ちます。ありがとう! –

関連する問題