Conosco le classi base Enum
e IntEnum
. Entrambi sono molto utili ma mi mancano le funzionalità per le operazioni di bandiera. Non mi aspetto che queste due classi implementino la mia funzionalità desiderata.Esiste una classe Python/enum per operazioni flag/bit mask?
Costruiamo un esempio:
class NetlistKind(IntEnum):
Unknown = 0
LatticeNetlist = 1
QuartusNetlist = 2
XSTNetlist = 4
CoreGenNetlist = 8
All = 15
Come potete vedere, sto già utilizzando IntEnum
per ottenere funzioni aritmetiche per questo enum. Sarebbe bello avere qualcosa come @unique
per garantire che tutti i valori siano una potenza di due. Posso farlo forking enum.unique per i miei bisogni. (Sono consapevole del fatto che All
è un'eccezione da quella regola)
Come viene utilizzata questa enumerazione?
filter = NetlistKind.LatticeNetlist | NetlistKind.QuartusNetlist
Grazie alle operazioni underlaying int bit sono possibili e filtro ha un valore interno 3.
Se sarebbe bello avere un "è bandiera X insieme filtro Y" funzione o meglio ancora un operatore. Aggiungo una funzione magico per x in y
: ad esempio
@unique
class NetlistKind(IntEnum):
Unknown = 0
LatticeNetlist = 1
QuartusNetlist = 2
XSTNetlist = 4
CoreGenNetlist = 8
All = 15
def __contains__(self, item):
return (self.value & item.value) == item.value
Usage:
....
def GetNetlists(self, filter=NetlistKind.All):
for entity in self._entities:
for nl in entity.GetNetlists():
if (nl.kind in filter):
yield nl
def GetXilinxNetlists(self):
return self.GetNetlists(NetlistKind.XSTNetlist | NetlistKind.CoreGenNetlist)
Quindi le domande sono:
- ci sono modi migliori per implementare campi di bit?
- Sono i modi migliori per implementare un filtro 1-D simile? Non voglio usare lamdas per una condizione di filtro così semplice?
- Questa soluzione è già inclusa nella libreria standard Python?
- Come aggiungere questa estensione enum alla prossima versione di Python? :)
caratteristiche aperte:
- restituirà un elenco di tutte le bandiere attive nel
__str__
- ...?
Ho recentemente attrezzato una mia biblioteca di bandiere con i test unitari e l'ho pubblicata su pypi. Sto per finire è README.rst e aggiungere alcune funzionalità extra nei prossimi giorni. La sua interfaccia è fortemente influenzata dal modulo enum standard di python3. Dai un'occhiata se sei interessato: https://pypi.python.org/pypi/py-flags Ho visto discussioni sul fatto che le bandiere siano o meno un approccio pitonico. I miei futuri aggiornamenti al README.rst avranno una sezione che discuterà i pro ei contro dell'utilizzo di diversi bool come funzioni args o memorizzazione di bool in un oggetto o dict VS usando set VS usando flags. – pasztorpisti
Si prega di inviare il tuo commento come risposta, quindi posso inversione di tendenza! Sembra molto buono e maturo. Solo una domanda: perché devo dare un FQN all'enum? Esempio: 'TextStyle ('TextStyle.bold')'.Penso che 'bold' sia sufficiente, perché lo spazio dei nomi è già limitato a' TextStyle', perché lo passi nel suo costruttore. – Paebbels
Link solo le risposte non sono benvenute su SO Mi spiace ... Il 'str()' dell'enumerazione può essere usato in altri contesti non solo in caso di serializzazione, questo è il motivo per cui '__str__' restituisce fqdn. Penso che 'str()' dovrebbe essere interpretabile anche senza la classe flags nel contesto. In realtà ai fini della serializzazione personalizzata ho fornito un 'to_simple_str()' oltre allo standard '__str__'. In questo caso 'to_simple_str()' emetterebbe semplicemente ''bold'' e' TextStyle (' bold ') 'funzionerebbe anche. In realtà il supporto serializzatore pickle di flag salva solo il nome della classe flags e l'output di 'to_simple_str()'. – pasztorpisti