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