Import Problems

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bill Jackson

    #1

    Import Problems

    Once again, I am having issues with imports...

    Until now, I thought the general guidelines were to rarely use 'from x
    import y' syntax, except when you really want to copy names over.
    However, I have run into issues by following this guideline. So...

    1) What is going wrong in the example below?
    2) What is a good way to handle imports for packages w/subdirectories?

    Here is a sample directory structure:

    importtest/
    __init__.py
    test2/
    __init__.py
    someclass.py
    mytest.py


    Here are the definitions of the files:

    # importtest/__init__.py
    from test2 import *

    # importtest/test2/__init__.py
    from someclass import *
    from test2 import *

    # importtest/test2/someclass.py
    class SomeClass:
    pass

    # importtest/test2/mytest.py
    import importtest
    print importtest.Some Class


    On import I get the following:
    >>import importtest
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    File "/home/user/lib/python/importtest/__init__.py", line 1, in ?
    from test2 import *
    File "/home/user/lib/python/importtest/test2/__init__.py", line 2, in ?
    from mytest import *
    File "/home/user/lib/python/importtest/test2/mytest.py", line 3, in ?
    print importtest.Some Class
    AttributeError: 'module' object has no attribute 'SomeClass'
    >>>

    The problem seems to be an 'order' issue. importtest/test2/__init__.py
    has loaded someclass.py, but it doesn't seem to have copied its contents
    into importtest/__init__.py.... perhaps it is because it hasn't finished
    all of its imports. Is this correct?

    So what is a good way to deal with this? In files which contain
    implementations , I thought it was best not to use 'from x import y', but
    this seems to be the only way to get this to work:

    # importtest/test2/mytest.py
    from someclass import SomeClass
    print SomeClass

    Is this the guideline?
    Use 'from x import y' for modules within your package.
    Use 'import y' for modules outside your package.

    Help.
  • Bill Jackson

    #2
    Re: Import Problems

    Bill Jackson wrote the following on 04/27/2007 12:49 PM:
    # importtest/test2/__init__.py
    from someclass import *
    from test2 import *
    Sorry typo here:

    # importtest/test2/__init__.py
    from someclass import *
    from mytest import *

    Comment

    • Robert Kern

      #3
      Re: Import Problems

      Bill Jackson wrote:
      Once again, I am having issues with imports...
      >
      Until now, I thought the general guidelines were to rarely use 'from x
      import y' syntax, except when you really want to copy names over.
      No, the guideline is to not use "from x import *" except at the interactive
      prompt and occasionally in __init__.py's to "copy names over" as you put it.
      However, I have run into issues by following this guideline. So...
      >
      1) What is going wrong in the example below?
      2) What is a good way to handle imports for packages w/subdirectories?
      >
      Here is a sample directory structure:
      >
      importtest/
      __init__.py
      test2/
      __init__.py
      someclass.py
      mytest.py
      >
      >
      Here are the definitions of the files:
      >
      # importtest/__init__.py
      from test2 import *
      >
      # importtest/test2/__init__.py
      from someclass import *
      from test2 import *
      >
      # importtest/test2/someclass.py
      class SomeClass:
      pass
      >
      # importtest/test2/mytest.py
      import importtest
      print importtest.Some Class
      >
      >
      On import I get the following:
      >
      >>import importtest
      Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "/home/user/lib/python/importtest/__init__.py", line 1, in ?
      from test2 import *
      File "/home/user/lib/python/importtest/test2/__init__.py", line 2, in ?
      from mytest import *
      File "/home/user/lib/python/importtest/test2/mytest.py", line 3, in ?
      print importtest.Some Class
      AttributeError: 'module' object has no attribute 'SomeClass'
      >>>
      >
      >
      The problem seems to be an 'order' issue. importtest/test2/__init__.py
      has loaded someclass.py, but it doesn't seem to have copied its contents
      into importtest/__init__.py.... perhaps it is because it hasn't finished
      all of its imports. Is this correct?
      You are right that it is an order issue. The line "from test2 import *" hasn't
      finished executing by the time "print importtest.Some Class" is executed because
      the former is trying to execute the latter.
      So what is a good way to deal with this? In files which contain
      implementations , I thought it was best not to use 'from x import y', but
      this seems to be the only way to get this to work:
      My recommendation is that inside packages, be as specific as is feasible with
      your imports, even if you expose the symbols at a higher level for external
      callers. If you have a module whose contents are being exposed in your
      __init__.py, never rely on the contents of that __init__.py in that code.
      Instead, go straight to the real modules that implement the symbols that you
      need. So mytest.py should read:

      from importtest.test 2.someclass import SomeClass
      print SomeClass

      or

      from importtest.test 2 import someclass
      print someclass.SomeC lass

      --
      Robert Kern

      "I have come to believe that the whole world is an enigma, a harmless enigma
      that is made terrible by our own mad attempt to interpret it as though it had
      an underlying truth."
      -- Umberto Eco

      Comment

      Working...