Самоанализ объекта библиотеки Python cffi приводит к изменению объекта __dict__
Я хотел бы получить полный список перечислений из заголовочного файла, используя 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()
сделать это заполняет __dict__
? призвание hasattr()
кажется, делает то же самое.
1 ответ
Технически причина того, что вы наблюдаете, заключается в том, что dir()
пытается получить несколько специальных атрибутов, таких как __members__
на lib
объект. Код в cffi лениво добавляет атрибуты по мере их вычисления. Если имя не найдено как функция, он приступает к установке всех объявлений перечислений и пытается вернуть одно из них, если это имя мы пытаемся прочитать. Вот почему попытка прочитать несуществующее имя всегда установит все перечисления в lib.__dict__
, (Эта логика только для библиотек, возвращаемых ffi.dlopen()
, не для режима API.)
В идеале, вы не должны полагаться ни на что из этого, но в этом случае вы должны: это действительно ошибка. Обратите внимание, что вы можете просто прочитать dir(lib)
дважды: во второй раз он будет содержать значения перечисления...
(Исправлена ошибка в 19cae8d1a5f6: как минимум dir(lib)
должен всегда работать в cffi 1.4--- и больше не перечислять все специальные имена методов Python.)