Elijah Newren wrote:
> Hi,
>
> I have three files in a simple testcase, and when I run
> $ main.py callee.options
> This comes back with a Traceback pointing out the following error:
> File "callee.options", line 5, in __init__
> Foo.__init__(self, value)
> NameError: global name 'Foo' is not defined
>
>
> The three files are:
>
> --------------- main.py ---------------
> #!/usr/bin/env python
>
> import sys
>
> class Stuff:
> def __init__(self, filename):
> self.greeting = 'Hi world'
> self.filename = filename
>
> def run(self):
> print self.greeting
> execfile(self.filename)
>
> work = Stuff(sys.argv[1])
> work.run()
> --------------- somelib.py ---------------
> class Foo:
> def __init__(self, value):
> self.value = value
>
> def do_stuff(self):
> raise NotImplementedError()
>
> class OfficialBar(Foo):
> def __init__(self, value):
> Foo.__init__(self, value)
>
> def do_stuff(self):
> print self.value
> --------------- callee.options ---------------
> from somelib import Foo, OfficialBar
>
> class MyBar(Foo):
> def __init__(self, value):
> Foo.__init__(self, value)
> #super(MyBar, self).__init__(value)
>
> def do_stuff(self):
> print 2 * self.value + 1
>
>
> baz = MyBar(7)
> #baz = OfficialBar(7)
> baz.do_stuff()
> ---------------------------------------------
>
> If I comment out the baz = MyBar(7) line, and uncomment the baz =
> OfficialBar(7) line, then there's no error.
>
> I'm sure this is somehow related to the fact that the execfile is
> within the Stuff class scope, and thus my import statements are
> working under some nested scope, but I don't know how to fix it (other
> modifying main.py to remove the Stuff class entirely, but in my real
> testcase I only have access to the callee.options file). I'm sure
> this is covered in some FAQ or post somewhere, but I seem to be coming
> up short in my search. If someone could someone point me to the
> relevant FAQ or post, I'd be more than happy to go read it.
execfile puts Foo in the local namespace of the Stuff.run() method, then
MyBar.__init__() looks it up in the global namespace and fails.
A quick and dirty fix may be to modify execefile to
execfile(self.filename, globals())
but you should seriously consider renaming callee.options and importing it
the normal way.
Peter
--
http://mail.python.org/mailman/listinfo/python-list