python cffi库对象内省导致__dict__对象改变

时间:2015-12-04 21:55:33

标签: python python-cffi

我想使用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__似乎做同样的事情。

1 个答案:

答案 0 :(得分:1)

从技术上讲,您观察到的原因是dir()尝试在__members__对象上获取一些特殊属性,例如lib。 cffi中的代码在计算时会懒惰地添加属性。如果找不到名称作为函数,它将继续安装所有枚举声明并尝试返回其中一个,如果这是我们尝试读取的名称。这就是为什么尝试读取不存在的名称将始终在lib.__dict__中安装所有枚举。 (此逻辑仅适用于ffi.dlopen()返回的库,而不适用于API模式。)

理想情况下,你不应该依赖任何一个,但在这种情况下你必须:它确实是一个错误。请注意,您只需阅读dir(lib)两次:第二次,它将包含枚举值... (修正了19cae8d1a5f6中的错误:至少dir(lib)应始终在cffi 1.4 ---中工作,并且不再列出所有特殊的Python方法名称。)