#python #enums #cython
#python #перечисления #cython
Вопрос:
Я ищу Cythonic способ (да, Cython) проверить, имеет ли объект тип Enum. В частности, я хочу различать целые числа и значения. Я ищу что-то вроде:
cdef extern from "Python.h":
bint PyObject_TypeCheck(object obj, PyTypeObject* type) nogil
PyObject_TypeCheck(obj, amp;PyEnumType_Type)
Но есть ли что-то вроде PyEnumType_Type, определенного где-нибудь?
Комментарии:
1. У вас должен быть, самое большее, один ответ.
Ответ №1:
Обычный старый isinstance(obj, Enum)
также отлично работает в Cython, но имеет ли он хорошую производительность? Возможно, я слишком много думаю об этом.
Комментарии:
1. Вы слишком много думаете об этом. Если вы посмотрите на сгенерированный код C для этого, он будет довольно эффективным
PyObject_TypeCheck
или похожим. Я бы не стал помещать его в быстрый внутренний цикл, если это возможно, но в принципе все в порядке2. Я принимаю этот ответ, потому что он работает и является самым простым и надежным ответом на исходный вопрос. Этот
getattr()
метод является хорошим способом решения моей первоначальной проблемы различения int и IntEnum в Cython, но будет регистрироваться как True для всего, что имеет атрибут «name».3. Вы также, вероятно, захотите использовать
IntEnum
вместоEnum
в своейisinstance()
проверке.
Ответ №2:
Я думаю, что, возможно, я нашел то, что искал. В PyEnum_Type
cpython/include/enumobject.h определено. Я попробую следующее:
cdef extern from "Python.h":
PyTypeObject PyEnum_Type
bint PyObject_TypeCheck(object obj, PyTypeObject* type) nogil
PyObject_TypeCheck(obj, amp;PyEnum_Type)
Комментарии:
1.
enumobject.h
не имеет ничего общего сEnum
.Enum
существует только как код Python.2. Хорошо, @EthanFurman. Есть ли у вас рекомендации о том, как различать объекты int и IntEnum, передаваемые функции в Cython?
Ответ №3:
Есть еще третий способ, который не требует импорта Enum в Cython.
if getattr(val, 'name', None) is not None