Cannot import module in same directory and package

一曲冷凌霜 提交于 2021-01-28 21:00:49

问题


I'm using a from . import module statement to do exactly that: import a local module to my script. The script and module reside in the same folder.

# module.py
def foo():
    print('Foo!')

# script.py
from . import module
module.foo()

> ImportError: cannot import name 'module'

This should be pretty easy, and doing just import module does work, but as this answer suggests one should, I modified the statements to the former form.

The end goal is to have a package, from which I can use things, but also to have executable scripts inside the package that import other parts of that package. Apparently, after a few days worth of searching and a few questions I still don't quite understand the import and packaging machinery.

These might be the cause:

  • Import statements are different in 2.7 and 3.x, I'm using 3.6, the question was on 2.7
  • Relative imports are different inside packages (folder with __init__.py)
  • The working directory is different or the folders are not in sys.path

Having an __init__ file does not make a difference at least in a fresh project in PyCharm. Also, the working directory is set to the folder of the sources and it is in path.

Have I missed something? Or rather, what's the correct way of achieving the functionality described in the end goal? Any help is greatly appreciated!


回答1:


Since writing this answer I have realised it is more convenient and better style in my humble opinion to install the package with pip install -e . and use absolute imports. So even within a package writing from package.sub.module import thing. This makes refactoring a lot easier and there's no need to ever manipulate module variables or sys.path.


When running a script directly, Python consideres the name (a special variable, __name__) of that script to be "__main__". In case of an import, the name is set to the name of the module. In the latter case relative imports are fine. But import actually looks at the combination of __name__ and another special variable, __package__, which is None for an executed script, but the path to a module for an imported module, e.g. parent.sub.

The searched variable is... drumroll...

__package__ + '.' + __name__

The secret ingredient is manipulating __package__:

# script.py
__package__ = 'package_name'   # or parent.sub.package
from . import module

This lets Python know you are inside a package even though the script is executed directly. However, the top level folder needs to be in sys.path and the package name has to reflect that directory structure.

See this very comprehensive answer on the topic of relative imports.



来源:https://stackoverflow.com/questions/51415425/cannot-import-module-in-same-directory-and-package

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!