Как цитонизировать глобальные __builtin__ объекты? - PullRequest
2 голосов
/ 04 октября 2019

У меня проблема с "cythonizing" проектом, написанным на python. 1. Создается экземпляр класса python (объявлен в файле myclass.py ), а затем "объявлен глобальным" с помощью setattr (__buildin __...) в файле main.py 2. Функция, объявленная в модуле (файл module.py ), обращается к этому экземпляру класса по его глобальному имени («globalclass») и устанавливает некоторые значения.

Таким образом, вопрос заключается в следующем: как цитонизировать модуль python, ссылаясь на экземпляр объекта по его «глобальному имени», определенному вне модуля с помощью setattr (__ builtin __...)?

Я запускаю Python 2.7.15 на Windows x86, с Cython 0.29.1. Приведенный ниже код прекрасно работает, когда я запускаю чистый python:

python main.py

Но цитонизация файла module.py выдает мне ошибку: необъявленное имя, не встроенное со ссылкой на глобальное имя экземпляра класса "globalclass".

Вот файл myclass.pyx , определение класса:

class Myclass:
    def __init__(self):
        self.value = ''

    def setValue(self,text):
        self.value = text

    def printValue(self):
        print self.value

Вот файл module.pyx : это файл, который я хочу процитировать, но cython говорит необъявленное имя не встроено"globalclass":

def setValue():
    globalclass.setValue('test from module.py')

Вот файл main.py (точка входа), в котором создается экземпляр класса, и "объявленный глобальным" с помощью setattr (__buildin __...):

import __builtin__
from myclass import Myclass
from module import setValue

if __name__ == '__main__':
    myclass = Myclass()
    setattr(__builtin__, 'globalclass', myclass)
    setValue()
    globalclass.printValue()

А вот файл setup.py , который используется для цитонизации всего:

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

cyextensions = [
    Extension(name='myclass', sources=['myclass.pyx']),
    Extension(name='module', sources=['module.pyx']),
    ]

setup(name='test',
      version = '0.0.1',
      description = 'test',
      packages = ['test'],
      ext_modules = cythonize(cyextensions)
)

А вот команда, которую я использую для цитонизации:

python setup.py build_ext --inplace

Вот сообщение об ошибке, которое я получаю при цитировании:

Error compiling Cython file:
------------------------------------------------------------
...
def setValue():
        globalclass.setValue('test from module.py')^
------------------------------------------------------------

module.pyx:2:1: undeclared name not builtin: globalclass

1 Ответ

3 голосов
/ 04 октября 2019

Это место, где Cython отличается от Python (хотя он не очень хорошо документирован). По сути, это предполагает, что он должен иметь возможность разрешать все глобальные имена во время компиляции, в то время как то, что вы делаете, влияет на него во время выполнения.

К счастью, есть возможность отключить это поведение ,Просто добавьте две строки в setup.py (как показано в документации выше)

from Cython.Compiler import Options
Options.error_on_unknown_names = False
...