Import, Inheritance, Scoping -- I'm doing something wrong with one ofthese

E

Elijah Newren

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.


Thanks,
Elijah
 
P

Peter Otten

Elijah said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top