2016-01-27 5 views
1

У меня возникают проблемы с Cython (с Python 3.5) с импортом между модулями в одном пакете.Ошибка относительного импорта Cython, даже при абсолютном импорте

Ошибка, которую я получаю, составляет SystemError: Parent module '' not loaded, cannot perform relative import, даже если я, по-видимому, делаю абсолютный импорт.

Ниже приведена простая тестовая установка, которую я использую. Это отлично работает с использованием версии pure-Python ниже (.py, а не .pyx и без компиляции), но не скомпилировано через Cython. Примечание. В приведенном ниже примере я не использую какие-либо функции языка Cython, просто компиляцию.

Кажется, что-то в структуре я не совсем прав? Но я просто не могу понять, как это работает правильно.

Структура файла:

PackageMain 
| 
+--__init__.py (this is empty) 
+--PackageMain.pyx 
+--SomeModule.pyx 
+--setup.py 

Файл PackageMain.pyx

from PackageMain.SomeModule import SomeClass2 # get same error with relative import, ie just .SomeModule 

class SomeClass1: 
     def __init__(self): 
      foo = SomeClass2() 

Файл SomeModule.pyx:

class SomeClass2: 
     def __init__(self): 
      print("Whoop!") 

Файл setup.py:

from distutils.core import setup, Extension 
from Cython.Build import cythonize 

extensions = [ Extension(language="c++", name="PackageMain", 
       sources=["PackageMain.pyx", "SomeModule.pyx"])] 

setup( name = 'Some name', 
     ext_modules = cythonize(extensions)) 

Выполнение from PackageMain import PackageMain с использованием файла .pyd, созданного Cython, приводит к вышеуказанной ошибке.

ответ

2

с помощью следующего кода/определений,

>>> from mytest import MainModule 
>>> dir(MainModule) 
['SomeClass1', 'SomeClass2', '__builtins__', '__doc__', 
'__file__', '__loader__', '__name__', '__package__', '__spec__', '__test__'] 

setup.py

from distutils.core import setup, Extension 
from Cython.Build import cythonize 

extensions = [ Extension(language="c++", 
       name="mytest.MainModule", sources=["mytest.MainModule.pyx"]), 
       Extension(language="c++", 
       name="mytest.SomeModule", sources=["mytest.SomeModule.pyx"])] 

setup( name = 'mytest', 
     ext_modules = cythonize(extensions)) 

mytest.MainModule.pyx

class SomeClass1: 
     def __init__(self): 
      foo = SomeClass2() 

mytest.SomeModule .pyx

class SomeClass2: 
     def __init__(self): 
      print("Whoop!") 

Когда питон загружает модуль расширения ABC, он ожидает найти функцию с именем initABC, который будет вызываться для инициализации модуля. Если два файла C++, сгенерированные cython, скомпилированы и помещены в одну общую библиотеку, функция init другого модуля на основе Cython не будет вызываться, и модуль не будет найден.

+0

Ах, они должны быть отдельными расширениями - спасибо. Это объясняет пару вещей: – Giswok

+0

J.J. Хакала, вы могли бы добавить немного более подробную информацию о том, почему именно они должны быть определены как отдельные расширения, пожалуйста? (вместо того, чтобы пытаться объединить несколько исходных файлов в одно расширение, как было раньше) – Giswok

+1

@ Giswok Я добавил несколько объяснений –

Смежные вопросы