[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