Типы расширения общего доступа к Cython: класс - PullRequest
0 голосов
/ 16 октября 2018

Я хочу создать класс на Cython, который будет читаем на Python.В настоящее время мои коды выглядят так, как показано ниже (конечно, они не совсем одинаковы, но структура и организация кодов одинаковы).

Насколько я понимаю, мы не можем напрямуюВызовите объект Cython из Python, поэтому я намеревался заставить класс TEST работать как оболочку, которая может быстрее вызывать класс Cython.
Однако я обнаружил, что объект класса в .pyx не может вызвать функцию cdef в классе Cythonized в том же файле, поэтому cdef class CYTEST имеет другую функцию-оболочку def func(), которая выглядит неэффективнойдля меня. (Этот абзац в моем первоначальном вопросе оказался неправильным)

Я обнаружил, что мы можем объявить объекты (такие как int, list и object) в.pxd файла, и мы можем прочитать объект в классе Cython из класса Python, определенного в файле .pyx (в приведенном ниже примере, print(self.cytest.somenum)).

Можем ли мы сделать то же самое с Cythonizedучебный класс?В этом примере мы можем напрямую вызвать Cyfunc() в TEST классе?

Часть main.py:

class MAIN:
    def __init__(self):
        cyobj1 = cyobj.CYTEST(self)
        cyobj2 = cyobj.CYTEST(self)
        cyobj1.func(3)

In cyobj.pyx

cdef class CYTEST:
    cdef object main
    cdef int somenum

    def __cinit__(self, object main):
        self.main = main
        self.somenum = 5
    def func(self, int num):
        return self.Cyfunc(num)

    cdef void Cyfunc(self, int num):
        print(num)
        self.main.cyobj2.Cyfunc(num+1) # what I want to do

cyobj.pxd:

cdef class CYTEST:
    cdef public object main
    cdef public int somenum
    cdef public void Cyfunc(self, int num)  # this doesn't work

Официальный документ не содержит примеров для моего случая.

1 Ответ

0 голосов
/ 16 октября 2018
self.main.cyobj2.Cyfunc(num+1) # what I want to do

Проблема в том, что он не знает, что self.main.cyobj2 является CYTEST, и, следовательно, невозможно вызвать Cyfunc.

. Самый простой вариант - броситьit:

cdef CYTEST o = self.main.cyobj2
o.Cyfunc(num+1)

(Вы получите TypeError, если произойдет сбой приведения).

Второй вариант - сделать функцию Cyfunc a cpdef так, чтобы онаможет быть вызван без знания типа обычным способом Python.

Третий вариант может также сделать MAIN a cdef class, а затем указать тип cyobj1 и cyobj2, кака также CYTEST.main.Однако это может вызвать проблемы с циклическими зависимостями, поэтому я не совсем уверен, что это возможно.

...