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 3 1499
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
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
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 This discussion thread is closed Replies have been disabled for this discussion. Similar topics
11 posts
views
Thread by Jason Kratz |
last post: by
|
reply
views
Thread by Jason Kratz |
last post: by
|
2 posts
views
Thread by kbass |
last post: by
|
1 post
views
Thread by Raaijmakers, Vincent \(GE Infrastructure\) |
last post: by
|
reply
views
Thread by John Roth |
last post: by
|
5 posts
views
Thread by Steve Holden |
last post: by
|
5 posts
views
Thread by Pekka Niiranen |
last post: by
|
10 posts
views
Thread by erick_bodine |
last post: by
|
18 posts
views
Thread by bobueland |
last post: by
|
3 posts
views
Thread by Emin |
last post: by
| | | | | | | | | | |