2013-05-13 15 views
5

Come descritto in PEP435, un enum può essere definito in questo modo:Come ottenere gli attributi nell'ordine in cui sono dichiarati in una classe Python?

class Color(Enum): 
    red = 1 
    green = 2 
    blue = 3 

E la risultante enum members di Color può essere iterata per definizione: Color.red, Color.green, Color.blue.

Questo mi ricorda Form in Django, in cui campi possono essere rese nell'ordine in cui sono dichiarati in un Form sottoclasse. Lo hanno implementato mantenendo un contatore di campo, ogni volta che viene creato un nuovo campo, il valore del contatore viene incrementato.

Ma nella definizione di Color, non abbiamo qualcosa come un FormField, come possiamo implementarlo?

risposta

10

In Python 3, è possibile personalizzare lo spazio dei nomi in cui una classe viene dichiarata con il metaclasse. Ad esempio, è possibile utilizzare un OrderedDict:

from collections import OrderedDict 

class EnumMeta(type): 

    def __new__(mcls, cls, bases, d): 
     print(d) 
     return type.__new__(mcls, cls, bases, d) 

    @classmethod 
    def __prepare__(mcls, cls, bases): 
     return OrderedDict() 


class Color(metaclass=EnumMeta): 
    red = 1 
    green = 2 
    blue = 3 

Questo stampa

OrderedDict([('__module__', '__main__'), ('red', 1), ('green', 2), ('blue', 3)]) 
+0

Mi chiedo se questo può essere fatto in Python2.x, così che facciamo un backport di 'enum'. – satoru

+0

Oh, non ho visto la tua risposta, esattamente! –

+0

No. Sei ridotto a '' 'FormField''' tipo hack di lì. –

4

In Python 2.x è possibile utilizzare this horrible hack ho scritto per rispondere a una domanda un po 'diversa, come fondamento per la funzionalità di questo ordinare. Quindi, davvero, non puoi. :-)

Problemi correlati