简体   繁体   中英

What is the correct way to import modules in python library?

When you write a python library, and want to import one module in it from another, what is the correct way to do it, so that imports work both when the library is imported from outside and when some unit tests are run from the library directory?

If you do

import some_module
from some_module import something

it works when run from the library directoy, but when imported from outside, produces ImportError: No module named 'some_module' .

You can do

from . import some_module
import my_library.some_other_module
from .some_module import something

but it will not work if you import the library from the unittest placed in the same directory.

Finally, you can play with sys.path and/or move unit tests to some other directory.

What's the best solution?

Edit: Just to make it clear, I'd like to run the unittests using python -m unittest in the top directory of the library. So far I made it work by adding

import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

to the beginning of the unit test files. As an alternative it's possible to write a short shell script that will add the parent directory to PYTHONPATH and then run unittests. I wonder if there are better ways to deal with it?

Take a look at the docs on Module Search Path

When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:

  • the directory containing the input script (or the current directory).
  • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
  • the installation-dependent default.

If you write a library, the test code should usually interface with the library in the same manner that a user of the library would. This might mean adding the module to the the search path either by setting the PYTHONPATH environment variable, or by installing the module in the default 3rd party module location.

I would suggest running your tests from the base directory which holds your modules using the automated test discovery option

python -m unittest discover (python >= 2.7)

This will recursively find files matching test_*.py (ie within module dirs), but should set the python path relative to the parent dir.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM