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

Elijah Newren newren at gmail.com
Sat Mar 7 15:28:53 EST 2009


Hi,

For some reason, Peter Otten's response is not showing up in my inbox,
but did show up in the mailing list archives
(http://mail.python.org/pipermail/python-list/2009-March/703850.html).
 So I'll respond to my own email, quote him, and respond that way.

On Sat, Mar 7, 2009 at 9:46 AM, Elijah Newren <newren at gmail.com> 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()
> ---------------------------------------------



And Peter Otten wrote:
> 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.

Ah, thanks for the explanation.  The big problem here is that real
case from which I drew main.py and somelib.py is cvs2svn.  I'm using a
system installed version of cvs2svn, and thus I only have control of
callee.options.  However, using your hint, I solved my problem by
changing the first line of callee.options from

from somelib import Foo, OfficialBar

to

global Foo
_temp = __import__('somelib', globals(), locals(), ['Foo', 'OfficialBar'])
Foo = _temp.Foo
OfficialBar = _temp.OfficialBar


Yeah, I agree it's ugly, but it's a use-once program anyway.  :-)

Thanks again,
Elijah



More information about the Python-list mailing list