Переопределение существующей функции Python в файле Cython pxd - PullRequest
1 голос
/ 24 февраля 2020

У меня есть функция, которая вызывается во внутренней l oop, поэтому я хочу использовать Cython для ускорения.

Добавление подсказок типа в файл .pxd помогает, но заменяет реализацию с небольшим количеством C magi c помогает еще больше, поэтому я попытался определить функцию в файле pxd, а затем заменить ее:

# test.py
import cython

def foo_():
    print('Hello world')

if not cython.compiled:
    foo = foo_
# test.pxd

# What I want:
# @cython.skipdefinition
# foo()


cdef inline void foo():
    print('Hello world from Cython')

И, конечно, это не удалось : test.py:7:4: Assignment to non-lvalue 'foo' потому что C не позволяет назначать функции.

Есть ли способ заменить существующую функцию Python в файле pxd?

1 Ответ

2 голосов
/ 04 марта 2020

Есть как минимум пара вариантов:

  1. Если вам не нужно разделять функцию cdef между несколькими модулями, вы можете поместить все это в .py файл и не использовать .pxd файл. Декоратор @cython.inline поможет вам в этом:

    import cython
    
    @cython.cfunc
    @cython.inline
    def foo():
        if cython.compiled:
            print("Hello world from Cython")
        else:
            print("Hello world")
    
  2. Если вам do нужно определение в файле .pxd, чтобы поделиться им между несколькими модулями, тогда вам нужно изменить назначение. Напишите вместо этого Python версию модуля globals() dict:

    # ... other code as you wrote it ...
    
    if not cython.compiled:
        globals()['foo'] = foo_
    

    С точки зрения Cython, это не отменяет имя C, так что все в порядке.

Я предпочитаю вариант 1, если это возможно, поскольку цель более ясна.

...