【问题标题】:Fetching a C variable value in an enum using its name (a Python string) in Python在 Python 中使用其名称(Python 字符串)获取枚举中的 C 变量值
【发布时间】:2016-09-08 12:40:36
【问题描述】:

基本上,我在 Python 中封装了一个 C API(使用 CFFI(非常棒))。

我在那个 C API 中有一个枚举:

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

在 Python 中,我以字符串的形式收到该枚举中的变量名称:"enum1"。我想得到value1

使用CFFI,您可以包装一个枚举并轻松访问其成员(here is an example)。我的问题是我有代表变量名称的字符串,而不是变量本身。

因此,cwrapper.c."enum1" 将不起作用(cwrapper 是包装模块的名称,cffi.dlopen(libname) 在包装库时返回的名称)。

我可以制作一个字典,将变量名作为字符串映射到真实变量,例如:

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

但此时,我最好将枚举重写为 Python 字典。

我知道我也可以使用正则表达式来读取 C 文件,但我认为还有一种更好的方法来处理它,这是我没有想到的。有什么想法吗?

【问题讨论】:

    标签: python c variables enums python-cffi


    【解决方案1】:

    cwrapper.c."enum1" 通常在 Python 中不是有效的语法。你需要使用getattr:

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

    然而,更简洁的方法是使用typeof 获取实际类型;然后得到它的relements,这是一本字典!

    >>> 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
    

    【讨论】:

    • 我实际上想指出它不是有效的语法。但是,我不知道getattr。谢谢,它有效!
    • 为什么使用这种方式比使用 getattr 更简洁?
    • 因为getattr 不仅可以检索枚举值,还可以检索包括printf 在内的任何内容,或刚刚包含在cdefs 中的任何内容。
    • 使用后者,您可以确保您只解析适当的值
    【解决方案2】:

    基于 Antti 的回答,可以构建一个合适的 Python Enum

    Strategy = enum.Enum('Strategy', ffi.typeof('strategy').relements)
    
    list(Strategy)
    # [<Strategy.RANDOM: 0>, <Strategy.IMMEDIATE: 1>, <Strategy.SEARCH: 2>]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      • 2021-07-25
      相关资源
      最近更新 更多