Why python finds module instead of package if they have the same name?

后端 未结 2 1248
无人及你
无人及你 2020-12-16 21:15

Here is my directory structure:

/home/dmugtasimov/tmp/name-res
    root
        tests
            __init__.py
            test_1.py
        __init__.py
              


        
2条回答
  •  天涯浪人
    2020-12-16 21:23

    I simplified the example from the question to demostrate that only four solutions are possible:

    • Explicit relative import from . import some_module or with more commas from ..
    • Relative import (without "xyz." if used in the package "xyz")
    • Absolute import using from __future__ import absolute_import (or use Python 3)
    • Never repeat the top level importable name of the package in any path inside it.

    What solution is the best? It depends on personal preference of Python 2 or 3. Only the last one is nice and universal for all Pythons. It was really a useful question.


    xyz/tests/__init__.py: import xyz.tests.t

    xyz/tests/t.py:

    import sys
    print('sys.path = %s' % sys.path) # see that the parent of "xyz" is on sys.path
    print("importing xyz.tests")
    import xyz.a
    

    xyz/a.py:

    # solution A: absolute_import by __future__  (or use Python 3)
    #from __future__ import absolute_import
    print("importing xyz.a")
    # solution B: explicit relative import
    #from . import b    # and remove "import xyz.b"
    # solution C: relative import (not recommended)
    #import b           # and remove "import xyz.b"
    import xyz.b
    

    xyz/b.py: print("imported xyz.b")

    xyz/xyz.py: print("Imported xyz.xyz !!!")

    xyz/__init__.py: empty file


    Everything possible fails, e.g.

    parent_of_xyz=...  # The parent directory of "xyz" - absolute path
    cd $parent_of_xyz
    python -m xyz.tests.t
    PYTHONPATH=$parent_of_xyz/xyz python -m unittest tests
    PYTHONPATH=$parent_of_xyz     python xyz/tests/t.py
    

    with messages like

    Imported xyz.xyz  !!!
    ...
    ImportError...
    

    If any solution is applied (uncommented), all three examples work.

    It can be more simplified without using any subdirectory.

    EDIT: I tried yesterday many tests but I wrote it inconsitently from different versions. Excuse me that it was unreproducible from the answer. Now it is fixed.

提交回复
热议问题