2016-12-31 63 views
23

Bir dizeyi bir Python Enum sınıfına dönüştürmenin (serpiştirmenin) doğru yolunun ne olduğunu merak ediyorum. İş getattr(YourEnumType, str) gibi görünüyor, ama yeterince güvenli olup olmadığından emin değilim.Dizeyi Python'da Enum'a dönüştür

class BuildType(Enum): 
    debug = 200 
    release = 400 

cevap

39

[1]:

>>> from enum import Enum 
>>> class Build(Enum): 
... debug = 200 
... build = 400 
... 
>>> Build['debug'] 
<Build.debug: 200> 

[1] resmi belgeler: Enum programmatic access

+0

Evet, aradığım şey buydu. Bu konuyla ilgili resmi belgelere bir bağlantı güzel olurdu. – Vladius

+0

@Vladius: Bağlantı eklendi. –

+0

Girişin dezenfekte edilmesi gerektiğinde geri dönüş değeri nedir? Build.get ('illegal', Build.debug) 'türünde bir şey var mı? – Hetzroni

1
def custom_enum(typename, items_dict): 
    class_definition = """ 
from enum import Enum 

class {}(Enum): 
    {}""".format(typename, '\n '.join(['{} = {}'.format(k, v) for k, v in items_dict.items()])) 

    namespace = dict(__name__='enum_%s' % typename) 
    exec(class_definition, namespace) 
    result = namespace[typename] 
    result._source = class_definition 
    return result 

MyEnum = custom_enum('MyEnum', {'a': 123, 'b': 321}) 
print(MyEnum.a, MyEnum.b) 

Yoksa Enum bilinen dize dönüştürmek gerekir:

Sadece daha belirgin olmak üzere

, böyle bir Enum nesnesine 'debug' dize dönüştürmek istersiniz?

class MyEnum(Enum): 
    a = 'aaa' 
    b = 123 

print(MyEnum('aaa'), MyEnum(123)) 

veya:

Bu işlevsellik daha önce Enum yerleşik olarak
class BuildType(Enum): 
    debug = 200 
    release = 400 

print(BuildType.__dict__['debug']) 

print(eval('BuildType.debug')) 
print(type(eval('BuildType.debug')))  
print(eval(BuildType.__name__ + '.debug')) # for work with code refactoring 
+0

yapabilirsiniz): debug = 200 release = 400 '' ' – Vladius

+0

Harika ipuçları! '__dict__'' getattr' ile aynı mı kullanıyor? Dahili Python öznitelikleriyle ad çarpışmaları hakkında endişeleniyorum .... – Vladius

+0

Oh ... evet, "getattr" ile aynı. İsim çarpışması için bir sebep göremiyorum. Anahtar kelimeyi sınıf alanı olarak ayarlayamazsınız. – ADR

0

Başka bir alternatif (özellikle dizeleriniz enum kasalarınızla 1-1 eşleşmiyorsa faydalıdır) staticmethod eklemek senin Enum, örneğin: `` `piton sınıf BuildType (Enum:

Sonra
class QuestionType(enum.Enum): 
    MULTI_SELECT = "multi" 
    SINGLE_SELECT = "single" 

    @staticmethod 
    def from_str(label): 
     if label in ('single', 'singleSelect'): 
      return QuestionType.SINGLE_SELECT 
     elif label in ('multi', 'multiSelect'): 
      return QuestionType.MULTI_SELECT 
     else: 
      raise NotImplementedError 

Eğer ben böyle bir enum bir` debug` dize dönüştürmek istiyoruz demek question_type = QuestionType.from_str('singleSelect')