How to fix “Attempted relative import in non-package” even with __init__.py

后端 未结 19 2589
予麋鹿
予麋鹿 2020-11-21 21:51

I\'m trying to follow PEP 328, with the following directory structure:

pkg/
  __init__.py
  components/
    core.py
    __init__.py
  tests/
    core_test.py         


        
相关标签:
19条回答
  • 2020-11-21 22:29

    This is very confusing, and if you are using IDE like pycharm, it's little more confusing. What worked for me: 1. Make pycharm project settings (if you are running python from a VE or from python directory) 2. There is no wrong the way you defined. sometime it works with from folder1.file1 import class

    if it does not work, use import folder1.file1 3. Your environment variable should be correctly mentioned in system or provide it in your command line argument.

    0 讨论(0)
  • 2020-11-21 22:30

    For me only this worked: I had to explicitly set the value of package to the parent directory, and add the parent directory to sys.path

    from os import path
    import sys
    if __package__ is None:
        sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
        __package__= "myparent"
    
    from .subdir import something # the . can now be resolved
    

    I can now directly run my script with python myscript.py.

    0 讨论(0)
  • 2020-11-21 22:31

    This approach worked for me and is less cluttered than some solutions:

    try:
      from ..components.core import GameLoopEvents
    except ValueError:
      from components.core import GameLoopEvents
    

    The parent directory is in my PYTHONPATH, and there are __init__.py files in the parent directory and this directory.

    The above always worked in python 2, but python 3 sometimes hit an ImportError or ModuleNotFoundError (the latter is new in python 3.6 and a subclass of ImportError), so the following tweak works for me in both python 2 and 3:

    try:
      from ..components.core import GameLoopEvents
    except ( ValueError, ImportError):
      from components.core import GameLoopEvents
    
    0 讨论(0)
  • 2020-11-21 22:32

    You can use import components.core directly if you append the current directory to sys.path:

    if __name__ == '__main__' and __package__ is None:
        from os import sys, path
        sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
    
    0 讨论(0)
  • 2020-11-21 22:32

    Old thread. I found out that adding an __all__= ['submodule', ...] to the __init__.py file and then using the from <CURRENT_MODULE> import * in the target works fine.

    0 讨论(0)
  • 2020-11-21 22:35

    As you have already marked everything as a module, there's no need to use the relative reference if you launch as python module.

    Instead of

    from ..components.core import GameLoopEvents
    

    simply

    from pkg.components.core import GameLoopEvents
    

    When you run from the parent of pkg, use the following

    python -m pkg.tests.core_test
    
    0 讨论(0)
提交回复
热议问题