By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,908 Members | 1,892 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,908 IT Pros & Developers. It's quick & easy.

Question about import and sys.path

P: n/a
Hi all

I am writing a business/accounting application. Once a user has logged
in they are presented with a menu. Each menu option has a description
and an associated file name and program name. The file name is the name
of a .py file (impName) and the program name is the name of a class in
that file which I instantiate to run the program (progName).

When a menu option is selected, I execute the program like this -
imp = __import__(impName)
app = getattr(imp,progName)()

All the .py files are stored in one directory, which I add to sys.path
at the beginning of the session. It all seems to work fine.

Now my program directory is getting cluttered, so I want to split it
into sub-directories, one per company (it is a multi-company system). I
can do that, and each of the subdirectories can be added to sys.path,
so it should work as at present.

However, I want the ability to have duplicate program names stored in
different subdirectories. At the time of selecting the menu option I
know which company is active, so I know which directory I want to run
the program from, but there does not seem to be a way to tell 'import'
to import from a particular directory. I could manipulate sys.path and
ensure that the correct company subdirectory is in the first position,
but that idea does not appeal to me. Maybe it is a good idea though - I
am open to suggestion.

Would 'execfile' be a good alternative? From what I can understand of
the docs it is almost equivalent, but I am not sure if there are any
implications. Here are some questions -

1. Does execfile create a .pyc file from a .py file, or does it compile
the contents of the file every time it is executed? If the latter, that
could create a performance problem.

2. The docs say 'it does not use the module administration -- it reads
the file unconditionally and does not create a new module'. What does
that mean? The main implication I can think of is that if the same
program is executed more than once in a given session, 'import' would
realise the second time that the module has already been imported, and
would not import it again, whereas 'execfile' would re-execute the file
every time. That could also create a performance hit, but I don't think
it would be too serious.

3. I assume that once a module has been imported, it stays in memory
for the life of the interpreter session. What happens with execfile?
Does it get garbage-collected after execution is complete?

4. Are there any other implications I should know about? I did read the
warning about modifying locals, but I don't do anything like that.

Thanks for any advice

Frank Millman

Nov 28 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a

Frank Millman wrote:
Hi all

I am writing a business/accounting application. Once a user has logged
in they are presented with a menu. Each menu option has a description
and an associated file name and program name. The file name is the name
of a .py file (impName) and the program name is the name of a class in
that file which I instantiate to run the program (progName).

When a menu option is selected, I execute the program like this -
imp = __import__(impName)
app = getattr(imp,progName)()

All the .py files are stored in one directory, which I add to sys.path
at the beginning of the session. It all seems to work fine.

Now my program directory is getting cluttered, so I want to split it
into sub-directories, one per company (it is a multi-company system). I
can do that, and each of the subdirectories can be added to sys.path,
so it should work as at present.

However, I want the ability to have duplicate program names stored in
different subdirectories. At the time of selecting the menu option I
know which company is active, so I know which directory I want to run
the program from, but there does not seem to be a way to tell 'import'
to import from a particular directory.
I suggest to use module `imp`.
For example:

I assume paths like this:

app/
importer.py
company1/
prog1.py
the module in the company1 subdirectory:

# prog1
class SomeClass(object):
def test(self):
return "%s: %s" % (__file__, self.__class__.__name__)

and the module with your menu could look like this:

# importer.py

def get_class(classname, impname, company):
fp, pathname, description = imp.find_module(impname, [company])
m = imp.load_module(impname, fp, pathname, description)
return getattr(m, classname)

obj = get_class("SomeClass", "prog1", "company1")()
print obj.test()

--
HTH,
Rob

Nov 28 '06 #2

P: n/a

Rob Wolfe wrote:
Frank Millman wrote:
Hi all

However, I want the ability to have duplicate program names stored in
different subdirectories. At the time of selecting the menu option I
know which company is active, so I know which directory I want to run
the program from, but there does not seem to be a way to tell 'import'
to import from a particular directory.

I suggest to use module `imp`.
For example:

I assume paths like this:

app/
importer.py
company1/
prog1.py
the module in the company1 subdirectory:

# prog1
class SomeClass(object):
def test(self):
return "%s: %s" % (__file__, self.__class__.__name__)

and the module with your menu could look like this:

# importer.py

def get_class(classname, impname, company):
fp, pathname, description = imp.find_module(impname, [company])
m = imp.load_module(impname, fp, pathname, description)
return getattr(m, classname)

obj = get_class("SomeClass", "prog1", "company1")()
print obj.test()
Perfect. Thanks very much, Rob.

One small point. The docs have the following warning -

"Important: the caller is responsible for closing the file argument, if
it was not None, even when an exception is raised. This is best done
using a try ... finally statement. "

I have added this to my code.

I wonder if you can avoid this in 2.5 by using the 'with' statement. I
am still using 2.4, so I cannot test. Anyway, your suggestion does
exactly what I want, and it works perfectly.

Thanks again.

Frank

Nov 29 '06 #3

P: n/a

Frank Millman wrote:
One small point. The docs have the following warning -

"Important: the caller is responsible for closing the file argument, if
it was not None, even when an exception is raised. This is best done
using a try ... finally statement. "

I have added this to my code.

I wonder if you can avoid this in 2.5 by using the 'with' statement. I
am still using 2.4, so I cannot test. Anyway, your suggestion does
exactly what I want, and it works perfectly.
Yes, of course. The `with` statement works exactly
as previously try...finally. I've tried it in 2.5 and it works
perfectly.
You have to use `from __future__ import with_statement`, though.
This statement will be always enabled in Python 2.6.

--
HTH,
Rob

Nov 29 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.