问题
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