I was afraid to use it in UnitTest without thinking about it with relative import of Python, or to dig up a directory, but I thought that I would seriously try to solve it, and I was able to solve it after investigating, so as a record I will leave it.
With the following directory structure
/package/
__init__.py
subpackage1/
__init__.py
moduleX.py
moduleY.py
subpackage2/
__init__.py
moduleZ.py
moduleA.py
moduleZ.py is moduleX.When importing py, that is, moduleZ.In the py file
```python
from ..subpackage1 import moduleX
Write
$ pwd
/package
$ cd subpackage2
$ python moduleZ.py
ValueError: attempted relative import beyond top-level package
## or
$ python subpackage2/moduleZ.py
ValueError: attempted relative import beyond top-level package
Can be reproduced safely.
Two solutions here [1] offered a very good solution. So I used it. This time
moduleZ.import py
```python
from subpackage1 import moduleX
Rewrite as
$ pwd
/package
$ python -m subpackage2.moduleZ
Take the method to solve with.
-m runs as a python script as a library module. So/package to root directory(__main__)As subpackage2/moduleZ.Since py is running, subpackage1/moduleX.You can import and execute py.
## Python's way of thinking about import
Python is [Package concept](https://www.python.org/doc/essays/packages/) [2] is the location where `` `python ~~~ .py``` is executed `` `root It recognizes as ``` and recognizes` `~~~ .py``` that exists under root as a module (` `~~~ .py```). Only one `` `~~~ .py``` script is recognized as this root. Furthermore, when you run the script with ``` python ~~~ .py```, Python's [`` __main__``` is a special case of import](https://docs.python.org/ja/3/ reference / import.html # special-considerations-for-main) [3] forces the module name to be `` `__ main__```. Therefore, the location of the execution directory is important as to which Python script is being executed by root (`` __main__```).
In this failure example, root (`` __main__```) will be the location of `` `moduleZ.py``` (this time, `` `subpackage2```).
```bash
$ pwd
/package
$ cd subpackage2
$ python moduleZ.py
## or
python subpackage2/moduleZ.py
As a result, when importing ( `subpackage1```) with relative import, trying to reference (
/ pacakge```) above root (``
subpackage2),
ValueError : attempted relative import beyond top-level packageand angry, Python script cannot be executed. By the way, REPL starting with
python has the current directory as` `__main__
, so you can import it by executing it in the root directory.
On the contrary, if you execute it in some package (directory), you may not be able to import it.
I used Python's import with a mysterious feeling that I didn't understand, so I was able to organize it relatively and became attached to it. I think there are many people who use `python -m`
in Python UnitTest if it is familiar. If you have any misunderstandings or typos due to insufficient research, I would appreciate it if you could describe them in the comments. Also, if you don't understand Python import honestly in this article, please take a look at the reference materials.
[1] Relative imports for the billionth time [2] Built-in Package Support in Python 1.5 [3] 5.8. Special considerations for main
Recommended Posts