views:

660

answers:

2

My application has a button to execute a python script dynamically using execfile. If I define a function inside the script (eg. spam()) and try to use that function inside another function (eg. eggs()), I get this error:

NameError: global name 'spam' is not defined

What is the correct way to call the spam() function from within eggs()?

#mainprogram.py
class mainprogram():
    def runme(self):
        execfile("myscript.py")

>>> this = mainprogram()
>>> this.runme()

# myscript.py
def spam():
    print "spam"

def eggs():
    spam()

eggs()

Also, I can't seem to be able to execute a method from my main application in the script. i.e.

#mainprogram.py
class mainprogram():
    def on_cmdRunScript_mouseClick( self, event ):
        execfile("my2ndscript.py")
    def bleh():
        print "bleh"

 #my2ndscript.py
 bleh()

The error is:

NameError: name 'bleh' is not defined

What is the correct way to call bleh() from my2ndscript.py?

EDIT: Updated first issue

A: 

Are you sure you posted the actual code you are having trouble with? The first script works fine for me.

The second error is to be expected: the name "bleh" is not defined in the outer block, only within the namespace of "mainprogram"

Peter Rowell
+1  A: 

In the second case you will need import (not sure whether "mainprogram.py" is on your $PYTHONPATH)

#mainprogram.py
class mainprogram:
    def runme(self):
        execfile("my2ndscript.py")
    def bleh(self):
        print "bleh"
if __name__ == '__main__':
    mainprogram().runme()

#my2ndscript.py
import mainprogram
x = mainprogram.mainprogram()
x.bleh()

but this will craete second instance of mainprogram. Or better yet:

#mainprogram.py
class mainprogram:
    def runme(self):
        execfile("my2ndscript.py", globals={'this': self})
    def bleh(self):
        print "bleh"
if __name__ == '__main__':
    mainprogram().runme()

#my2ndscript.py
this.bleh()

I guess that execfile is not right solution for your problem anyway. Why don't you use import or __import__ (and reload() in case script may change between those clicks).

#mainprogram.py
import my2ndscript

class mainprogram:
    def runme(self):
        reload(my2ndscript)
        my2ndscript.main(self)
    def bleh(self):
        print "bleh"

if __name__ == '__main__':
    mainprogram().runme()

#my2ndscript.py
def main(program):
    program.bleh()
lispmachine