2016-09-12 16 views
6

Ben aslında bir iletişim protokolünün bir kısmı için Çeteleler temsil Python otomatik oluşturulan sınıfların büyük miktarda var, onlar bu şekilde de otomatik jeneratör ve kolaylaştırır böyleceSınıf değişkenlerini python alt sınıfına dinamik olarak ekleyebilir misiniz?

# definitions.py 

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

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

# etc etc etc 

şeyler tanımlanması gibi bakmak insanlar için değişiklik yapmak. ParamEnum sınıfı gelen ağ verilerinden tüm işlevselliği almak/ayarı, karşılaştırma, dönüşüm ve oluşturulmasını sağlar ve

Ancak bu sınıflar bazı ekstra meta verileri gerektirir vb. Ben onu daha az okunabilir yapar gibi olsa her sınıfın kaynak tanımına bu eklemek istemiyorum ve ben ancak bu

# param_enum.py 

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

gibi yapıyorum anda autogenerator

kıracak Bu, her zaman, bu Enumlardan birini (her zaman gerçekleşir), yalnızca tanımda değil (metadata değişmez, bu yüzden sadece bir kez ayarlanması gerekir) her an gerçekleşeceğinden vurur.

I bunu tanım dosyasının sonuna ekledi, ancak sorunla karşılaştı Orada da.

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 

alt sınıflarına miras edilebilir/geçersiz kılma sınıf tanımlandığında işlevsellik ekleme Python yolu var mı? Bir sınıf veya işlev değişikliği sahip olduğu sonrası: İdeal bir sınıf dekoratör

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

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

dekoratörler için çok motivasyon aslında Ne yapmak isterseniz bunu kullanın

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

Python'da, Sınıflar Meta sınıflarının örnekleridir. Yani, ParamEnum'unuzu '__new__' geçersiz kılan bir Meta Sınıfı vererek bunu başarabilirsiniz. – Phillip

cevap

5

gibi bir şey istiyorum oluşturuldu. Eğer dekoratörler haberiniz yoksa

, this (biraz uzun olsa da) okuyun.

Ayrıca metaclasses kullanabilirsiniz, ancak bir dekoratör daha fazla karmaşıklık tanıtmak. Ek dekorasyon hattını @add_metadata önlemek istiyorsanız ve bunu belirtilen alt sınıf ParamEnum göre gereksiz olduğunu düşünüyorum, ayrıca temel sınıf ParamEnum içinde tembel değerlendirmeyle _metadataa descriptor yapabiliriz.

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

Bence bir betimleyici dekoratörden daha iyi. –

+0

@AlbertLee Ben de, o tanıtıcı daha zarif olduğunu düşünüyorum. Ancak, kodun kimin tarafından korunduğuna bağlı olarak bir engel olabilecek oldukça gelişmiş "sihir" lerdir. –

+0

Tanımlayıcı ile gitti, oldukça güzel çalışıyor ve otomatik olarak oluşturulan dosyam temiz tutuyor. Teşekkürler! –

İlgili konular