You're 3 years 8 months wiser since you posted so I'm assuming you'd have figured the first issue out, but given that a solution has not yet been posted (primarily because no one seemed to have a problem with the first issue), the following is my solution.
[UPDATED]
The last solution I provided was incorrect. Below I am providing the correct solution and explaining it in detail using code that I executed.
The problem is inherent in Python's execfile()
builtin. Its one of the reasons that function has been deprecated in Python 3.x.
When you executed execfile()
inside runme()
, the objects spam()
and eggs()
were loaded into method runme()
's namespace, and not into the global namespace (as they should ideally be). Consider the following code:
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()
Interpreter Output
>>>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>}
From the output you can see that spam()
is not in the global namespace, but in method runme()
's namespace. So hypothetically, the correct way to call spam()
would have been
def eggs():
global this
this.runme.spam()
However, there is no way to access spam()
while it is lying inside runme()
's namespace. The solution, therefore, is to insert spam()
in the global namespace as follows:
myscript.py
global spam
def spam():
print "spam"
def eggs():
spam()
eggs()
This will ensure that a reference to object spam()
is created inside the globals()
dictionary (i.e., the global namespace), making it callable from eggs()
.