2016-05-12 4 views
1

Im Grunde bin ich ein C-API in Python (mit CFFI (was super ist)).Abrufen eines C-Variablenwerts in einem Enum unter Verwendung seines Namens (eine Python-Zeichenfolge) in Python

Ich habe eine ENUM in diesem C API:

typedef enum 
{ 
    enum1 = value1; 
    enum2 = value2; 
    ... 
} enumSomething; 

In Python, I erhalten den Namen einer Variablen, die in dieser Aufzählung ist, als String: "enum1". Ich möchte value1 bekommen.

Mit CFFI können Sie eine Enum umbrechen und auf ihre Mitglieder zugreifen (here is an example). Mein Problem hier ist, dass ich Strings habe, die den Namen der Variablen darstellen, nicht die Variable selbst.

So cwrapper.c."enum1" würde nicht funktionieren (cwrapper der Name des Moduls ist, der den Namen von ffi.dlopen(libname) zurück Wraps und c während der Bibliothek Verpackung).

Ich könnte ein Wörterbuch machen, die den Variablennamen als String in die reale Variable, wie Karte würde:

enum = { "enum1" : cwrapper.c.enum1, "enum2" : cwrapper.c.enum2, ... } 

Aber an diesem Punkt würde ich besser schreiben die Enum als Wörterbuch Python.

Ich weiß, ich könnte auch eine Regex verwenden, um die C-Datei zu lesen, aber ich denke, es gibt noch einen besseren Weg für die Handhabung, an die ich nicht gedacht habe. Irgendeine Idee?

Antwort

3

cwrapper.c."enum1" ist keine gültige Syntax in Python im Allgemeinen. Sie müssen verwenden getattr:

>>> getattr(cwrapper.c, "enum1") 
42 

jedoch ein sauberer Ansatz ist es, die tatsächliche Art mit typeof zu erhalten; dann erhalten Sie seine relements, die ein Wörterbuch ist!

>>> import cffi 
>>> ffi = cffi.FFI() 
>>> ffi.cdef('typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;') 
>>> typeof_strategy = ffi.typeof('strategy') 
>>> typeof_strategy.relements 
{'RANDOM': 0, 'SEARCH': 2, 'IMMEDIATE': 1} 
>>> typeof_strategy.relements['SEARCH'] 
2 
+0

ich darauf hinweisen, eigentlich wollte, dass es nicht ein gültige Syntax wäre. Allerdings wusste ich nichts über getattr. Danke, es funktioniert! – DRz

+0

@DRz siehe meine aktualisierte –

+0

Warum sollte es sauberer sein, anstatt nur getattr zu verwenden? – DRz

2

Aufbauend auf Antti Antwort, ein Enum richtiger Python gebaut werden kann:

Strategy = enum.Enum('Strategy', ffi.typeof('strategy').relements) 

list(Strategy) 
# [<Strategy.RANDOM: 0>, <Strategy.IMMEDIATE: 1>, <Strategy.SEARCH: 2>] 
Verwandte Themen