Loading and executing an arbitrary Python script from within Python

TheDustbustr thedustbustr at aol.com
Sat Jul 26 15:46:24 CEST 2003


I'm writing a game in C++ that calls out to Python for scripting.  The C++
kernel holds an instance of ScriptCtl and calls the load(filename) method to
load a script, then run() to run all loaded scripts.

<code>
[scriptctl.py]
class ScriptCtl:
    threads=[]

    def load(self, filename):
        f=file(filename, 'r')
        contents=f.read()
        f.close()
        exec(contents) #contents exec'ed within the current scope and
namespace, not within their own
        self.threads.append(main)
    
    def run(self):
        while self.threads:
            for g in self.threads:
                try:
                    g.next()
                except StopIteration:
                    self.threads.remove(g)

[cutscene.py]
from __future__ import generators
def cutscene():
    from time import time
    import sys
    from utility import sleep
    
    print "EVIL KNIGHT: I will kill you now!"; sys.stdout.flush()
    for s in sleep(1): yield None
    print "OUR HERO: I shall fight you to the death.  Bring it on!";
sys.stdout.flush()
    for s in sleep(1.5): yield None
    print "***End of cutscene***"; sys.stdout.flush()

main=cutscene() #initialize the generator for use by scriptctl
</code>

This works, barely.  As a result of using exec, each script is executed in
ScriptCtl.load()'s namespace.  Because of this, imports have to be done inside
the script functions, or the imports go out of scope before the functions get
called (in scriptctl.run()).  Imports also have to be done as from
scriptctl.py, even though scriptctl.py deeper in the package hierarchy (so
instead of 'import core.utility' I must do 'import utility' because both
utility.py and scriptctl.py are in the same folder (core).

This sucks.

How else can I solve this problem?  Ideally, I'd use Stackless Python
microthreads, but version 3.0 is not out yet and there is no documentation on
the current was to do microthreads.

Any ideas?  I'm stuck.
Thanks, Dustin




More information about the Python-list mailing list