Какой наилучший способ проверить, является ли объект перечислением в Cython?

#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