beyond top level package error in relative import

后端 未结 13 2440
醉梦人生
醉梦人生 2020-11-22 12:50

It seems there are already quite some questions here about relative import in python 3, but after going through many of them I still didn\'t find the answer for my issue. s

13条回答
  •  春和景丽
    2020-11-22 13:09

    This is very tricky in Python.

    I'll first comment on why you're having that problem and then I will mention two possible solutions.

    • What's going on?

    You must take this paragraph from the Python documentation into consideration:

    Note that relative imports are based on the name of the current module. Since the name of the main module is always "main", modules intended for use as the main module of a Python application must always use absolute imports.

    And also the following from PEP 328:

    Relative imports use a module's name attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to 'main') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

    Relative imports work from the filename (__name__ attribute), which can take two values:

    1. It's the filename, preceded by the folder strucutre, separated by dots. For eg: package.test_A.test Here Python knows the parent directories: before test comes test_A and then package. So you can use the dot notation for relative import.
    #  package.test_A/test.py
    from ..A import foo
    

    You can then have like a root file in the root directory which calls test.py:

    #  root.py
    from package.test_A import test
    
    1. When you run the module (test.py) directly, it becomes the entry point to the program , so __name__ == __main__. The filename has no indication of the directory structure, so Python doesn't know how to go up in the directory. For Python, test.py becomes the top-level script, there is nothing above it. That's why you cannot use relative import.

    • Possible Solutions

    A) One way to solve this is to have a root file (in the root directory) which calls the modules/packages, like this:

    • root.py imports test.py. (entry point, __name__ == __main__).
    • test.py (relative) imports foo.py.
    • foo.py says the module has been imported.

    The output is:

    package.A.foo has been imported
    Module's name is:  package.test_A.test
    

    B) If you want to execute the code as a module and not as a top-level script, you can try this from the command line:

    python -m package.test_A.test
    

    Any suggestions are welcomed.

    You should also check: Relative imports for the billionth time , specially BrenBarn's answer.

提交回复
热议问题