Вы на 3 года и 8 месяцев мудрее с момента публикации, поэтому я предполагаю, что вы уже разобрались с первой проблемой, но, учитывая, что решение еще не опубликовано (в первую очередь потому, что, похоже, ни у кого не было проблем с первая проблема), следующее мое решение.
[ОБНОВЛЕНО]
Последнее решение, которое я предоставил, было неверным. Ниже я предоставляю правильное решение и подробно объясняю его, используя код, который я выполнил.
Проблема присуща встроенному в Python execfile()
. Это одна из причин того, что эта функция устарела в Python 3.x.
Когда вы выполняли execfile()
внутри runme()
, объекты spam()
и eggs()
были загружены в пространство имен метода runme()
, а не в глобальное пространство имен (как в идеале должно быть) . Рассмотрим следующий код:
myscript.py
def spam():
print 'spam'
def eggs():
if 'spam' not in globals():
print 'method spam() is not present in global namespace'
spam()
try:
eggs()
except Exception as e:
print e
mainprogram.py
class mainprogram():
def runme(self):
execfile("myscript.py")
print 'Objects lying in local namespace of runme() are -'
print locals()
this = mainprogram()
this.runme()
Вывод интерпретатора
>>>import mainprogram
method spam() is not present in global namespace
name 'spam' is not defined
Objects lying in local namespace of runme() are -
{'e': NameError("name 'spam' is not defined",), 'spam': <function spam at 0x000000000000002B>, 'eggs': <function eggs at 0x000000000000002C>, 'self': <mainprogram.mainprogram instance at 0x000000000000002D>}
Из вывода видно, что spam()
находится не в глобальном пространстве имен, а в пространстве имен метода runme()
. Таким образом, гипотетически, правильный способ вызова spam()
был бы
def eggs():
global this
this.runme.spam()
Однако нет способа получить доступ к spam()
, пока он находится внутри пространства имен runme()
. Поэтому решение заключается в том, чтобы вставить spam()
в глобальное пространство имен следующим образом:
myscript.py
global spam
def spam():
print "spam"
def eggs():
spam()
eggs()
Это обеспечит создание ссылки на объект spam()
внутри словаря globals()
(т. Е. Глобального пространства имен), что сделает его доступным из eggs()
.