我想使用cffi从头文件中获取枚举的完整列表。但是我看到一个奇怪的行为:通过观察对象,我迫使基础__dict__
中的变化:
>>> from cffi import FFI
>>> ffi = FFI()
>>> ffi.cdef('typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;')
>>> c = ffi.dlopen('c')
# the dictionary is empty
>>> print c.__dict__
{}
>>> dir(c)
# the dictionary is populated
>>> print c.__dict__
{'SEARCH': 2, 'RANDOM': 0, 'IMMEDIATE': 1}
我猜测在调用类的第一个__dict__
之前不会填充getattr()
,但真正的问题是:填充dir()
的{{1}}做了什么?调用__dict__
似乎做同样的事情。
答案 0 :(得分:1)
从技术上讲,您观察到的原因是dir()
尝试在__members__
对象上获取一些特殊属性,例如lib
。 cffi中的代码在计算时会懒惰地添加属性。如果找不到名称作为函数,它将继续安装所有枚举声明并尝试返回其中一个,如果这是我们尝试读取的名称。这就是为什么尝试读取不存在的名称将始终在lib.__dict__
中安装所有枚举。 (此逻辑仅适用于ffi.dlopen()
返回的库,而不适用于API模式。)
理想情况下,你不应该依赖任何一个,但在这种情况下你必须:它确实是一个错误。请注意,您只需阅读dir(lib)
两次:第二次,它将包含枚举值...
(修正了19cae8d1a5f6中的错误:至少dir(lib)
应始终在cffi 1.4 ---中工作,并且不再列出所有特殊的Python方法名称。)