Question about import and sys.path

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Frank Millman

    Question about import and sys.path

    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__(impN ame)
    app = getattr(imp,pro gName)()

    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

  • Rob Wolfe

    #2
    Re: Question about import and sys.path


    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__(impN ame)
    app = getattr(imp,pro gName)()
    >
    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(objec t):
    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(class name, 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("Some Class", "prog1", "company1") ()
    print obj.test()

    --
    HTH,
    Rob

    Comment

    • Frank Millman

      #3
      Re: Question about import and sys.path


      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(objec t):
      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(class name, 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("Some Class", "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

      Comment

      • Rob Wolfe

        #4
        Re: Question about import and sys.path


        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

        Comment

        Working...