[Tutor] Importing global variables and classes from other modules
Danny Yoo
dyoo at hkn.eecs.berkeley.edu
Mon Dec 22 15:16:36 EST 2003
On Mon, 22 Dec 2003, Stanfield, Vicki {D167~Indianapolis} wrote:
> > > But my problem is that the functions and other global variables
> > > present sub are not getting imported to my main module. Can any body
>
> > > suggest me what is the right method to do, the condition being that
> > > the import should happen only if I call f1.
> >
> > Wait, wait. Doing a conditional import might be a very bad idea from
> > a debugging standpoint.
> >
> > Can you show us why you want to import this way? That context might
> > help us to suggest better alternatives, if there are any.
>
> Isn't a conditional import often done for multi-platform work? If my
> program is intended to run on Windows and Linux, I often do conditional
> importing. Is there a problem with that that I don't know of?
I should be less polemical. *grin*
Multi-platform work is one place where doing a conditional import is
probably ok. And pygame --- a popular module for doing games/GUI
programming --- itself uses a lot of conditional imports to fail safely if
the sound device isn't working. For example, here's a portion of what
Pygame does when it tries loading in its modules:
###
#next, the "standard" modules
#we still allow them to be missing for stripped down pygame distributions
try: import pygame.cdrom
except (ImportError,IOError), msg:cdrom=MissingModule("cdrom", msg, 1)
try: import pygame.cursors
except (ImportError,IOError), msg:cursors=MissingModule("cursors", msg, 1)
try: import pygame.display
except (ImportError,IOError), msg:display=MissingModule("display", msg, 1)
###
http://cvs.seul.org/cgi-bin/cvsweb-1.80.cgi/games/pygame/lib/__init__.py?rev=1.29&content-type=text/x-cvsweb-markup
So this conditional import is a technique that is used. But its use is
fairly limited to things like loading platform-dependent libraries. In
Venkatesh's case, though, I'm not sure that it's such a good idea to do a
conditional import.
Let's see his message:
> My program will be creating classes dynamically and I wish to save those
> class definitions into the file and retrive these definitions at some
> other point in time. I first thought of a simple strategy of storing the
> class definition in file as a string and later executing the string so
> that the class is created.
Yes, this sounds reasonable.
> But the class gets created inside the function in which i call exec and
> its scope is confined to that function
Are you sure about this? I'm not quite sure I understand why scope is
significant here --- it should be perfectly possible to construct classes
from an evaluated class definition, regardless of the scope. Here's an
example:
###
>>> s = '''
... class Person:
... def sayHello(self):
... print "Hello world!"
... '''
>>> d = {'__name__': 'DynamicCode', '__builtins__': None}
>>> exec s in d
###
Here, the Person class doesn't live directly in the global namespace,
###
>>> Person
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'Person' is not defined
###
But it resides in the small dictionary 'd' that we've set up.
###
>>> d['Person']
<class DynamicCode.Person at 0x400e292c>
###
And we can still construct Person instances:
###
>>> joe = d['Person']()
>>> joe.sayHello()
Hello world!
###
This has the slight advantage of being able to limit the scope of the
dynamic classes to a small dictionary, so that it doesn't have the
opportunity to kludge up our namespace. If we package this up in a nice
function, everything works as expected still:
###
>>> def extractClass(text, class_name):
... d = {'__name__': 'DynamicCode', '__builtins__' : None}
... exec text in d
... return d[class_name]
...
>>> MyClass = extractClass(s, 'Person')
>>> mary = MyClass()
>>> mary.sayHello()
Hello world!
###
Venkatesh, would this be ok for you?
Good luck!
More information about the Tutor
mailing list