2015-02-20 2 views
0

Я пишу оптимизатор байт-кода Python для модуля, который ранее имел целую цепочку инструментов Cython. Хотя это может быть устарело к настоящему времени, я столкнулся с чем-то странным, играя с ним. Рассмотрим этот простой кусок кода:Cython: использовать globals(). Update (...)?

from opcode import opmap 

globals().update(opmap) 

print(STORE_GLOBAL) 

Это должно напечатать 97, а STORE_GLOBAL определяется в opmap с опкодом (который 97). Cython скажет мне, что STORE_GLOBAL не определен, хотя:

Error compiling Cython file: 
------------------------------------------------------------ 
... 
from opcode import opmap 

globals().update(opmap) 

print(STORE_GLOBAL) 
       ^
------------------------------------------------------------ 

test.py:5:18: undeclared name not builtin: STORE_GLOBAL 

Причина этого довольно легко, я думаю. Я предполагаю, что он не обновляет глобальные переменные, поэтому он не знает о STORE_GLOBAL, который теперь является переменной.

Есть ли неудобный способ преодолеть эту проблему?

Приветствия

ответ

2

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

Однако большинство переменных не видны для python. Эти переменные объявляются во время компиляции и статически типизируются. Предполагается, что любая переменная, на которую ссылается, которая не объявлена ​​в модуле, является ошибкой, скорее надеясь, что переменная будет добавлена ​​позже к глобальным модулям.

Единственный способ обойти это - обратиться к таким переменным через глобальные модули. Не очень элегантный.

print(globals()["STORE_GLOBAL"]) 

Лучшие альтернативы импортировать opmap и обратитесь к соответствующим значениям через это. Или выписать значения в opmap verbatim в вашем модуле.

+0

Да, это то, о чем я думал. Спасибо за ваше разъяснение. – hellerve

0

Я не знаю, было ли это документировано в любом месте, но я обнаружил, что если имя объявлено в операторе global в любой функции модуля Cython, то в дополнение к стандартному значению Python «это имя должен быть прочитан и записан как глобальная переменная в этой функции », также имеет побочный эффект, позволяющий присвоить имя как глобальную переменную, всюду в модуле, подавляя ошибку в вопросе.

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