Python Submodule Importing Madness

前端 未结 2 1274
误落风尘
误落风尘 2021-01-17 05:01

I\'m banging my head against the wall with some basic Python importing. I have simplified the problem as much as possible hoping I\'d be able to expand this to a larger scal

相关标签:
2条回答
  • 2021-01-17 05:07

    Python makes it intentionally difficult to mix scripts in a modules. The way this can be handled is like this:

    /project
        /scripts
            run.py
        /sandbox
            __init__.py
            /p1
                __init__.py
                file1.py
                file2.py
    

    /project/sandbox/p1/file1.py

    from .file2 import B
    class A(object):
        pass
    

    /project/sandbox/p1/file2.py

    class B(object):
        pass
    

    /project/scripts/run.py

    from sandbox.p1.file1 import A
    a = A()
    

    I make sure that the path to /project is in a .pth file in the site-packages of the virtual environment I want to use it from.

    conda

    If you use conda, you can use conda develop

    0 讨论(0)
  • 2021-01-17 05:14

    (I) no module named 'file2'

    You encountered No module named 'file2' because you run run.py outside a package, when file1 import file2, python cannot find file2 as the module directory not in module search path.

    For your scenario, file1 & file2 are 2 modules which in the same package, for this situation, suggest you use relative import, this is the best practice.

    file1.py

    from .file2 import B
    class A(object):
        pass
    

    Then, python run.py works.

    (II) attempted relative import with no known parent package

    As you mentioned you will see next if execute python p1/run.py:

    attempted relative import with no known parent package

    What does it mean?

    This because relative import can just be supported in the module which in package.

    You may say file1.py is in package p1, why still see the error?

    This is because python use __name__ to determine if this module in package or not, not by the position of it.

    Change file1.py as follows:

    print(__name__)
    from .file2 import B
    class A(object):
        pass
    

    Next is the output:

    python run.py

    p1.file1

    python p1/run.py

    file1

    For python p1/run.py, because it runs in the package, python will fail to know it is in a package, so output is file1.

    If __name__ does not has ., python will think it's not in package, so relative import failure.

    (III) Finally, what if you really want to execute python p1/run.py, e.g. unittest your package?

    Use python -m p1.run, this should works to execute top script which inside a package.

    0 讨论(0)
提交回复
热议问题