4

I have a project structured as this:

parent/
   sub1/
      __init__.py
      directoryManager.py
   sub2
      tst.py

in tst.py, I am trying to import directoryManager as ld from sub1, is there anyway to import it without using sys.path.append ?

Thanks very much

Jialiang Zhou
  • 83
  • 1
  • 7

3 Answers3

0

You could use:

from .. import directoryManager

The extra . goes one dictionary up

If this is going to be a package installed to path from parent parent.sub1 import directoryManager

Xantium
  • 11,201
  • 10
  • 62
  • 89
  • it gives me attempted relative import in non package error – Jialiang Zhou Feb 13 '18 at 23:50
  • @JialiangZhou Does this post help: https://stackoverflow.com/questions/14664313/attempted-relative-import-in-non-package-although-packages-with-init-py-in – Xantium Feb 13 '18 at 23:58
  • well,not really cause the tst.py are scheduled to run via a server using python not python -m, I was thinking if I can put the directoryManager to a root directory of the computer – Jialiang Zhou Feb 14 '18 at 00:02
  • @JialiangZhou Unless I'm understanding the meaning of `root dictionary` incorrectly `from parent.sub1 import directoryManager` sould work – Xantium Feb 14 '18 at 00:11
  • I add the package to python/site-packages but it works in Linux only . In windows, I put is at python27/Lib/site-packages but doesn't work – Jialiang Zhou Feb 14 '18 at 00:13
  • @JialiangZhou Hmm is site-packages added to the path variable? – Xantium Feb 14 '18 at 00:16
  • I think so cause I saw other scrip import package located in site-packages – Jialiang Zhou Feb 14 '18 at 00:23
  • @JialiangZhou All I can suggest is create your setup.py file and install it. – Xantium Feb 14 '18 at 00:25
0
import os
import sys

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

from sub1 import directoryManager

This should work.

chemical
  • 378
  • 1
  • 10
0

Recipe 1

import importlib.machinery
import importlib.util
import sys
from pathlib import Path

finder = importlib.machinery.PathFinder()
spec = finder.find_spec(
    'directoryManager',
    [str(Path(__file__).resolve().parent.parent / 'sub1')]
)
# or finder.find_spec('directoryManager', ['../sub1']) if cwd is sub2
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)

This recipe doesn't need the full path of the file. Thus it is useful for importing extensions (they have suffixes like .cpython-38-aarch64-linux-gnu.so).

Recipe 2

import importlib.util
import sys
from pathlib import Path

spec = finder.spec_from_file_location(
    'directoryManager',
    str(Path(__file__).resolve().parent.parent / 'sub1' / 'directoryManager.py')
)
# or finder.spec_from_file_location('directoryManager, '../sub1/directoryManager.py') if cwd is sub2
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)

This recipe is more straightforward and simple. Adapted from https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly

Reference

https://docs.python.org/3/library/importlib.html#checking-if-a-module-can-be-imported (importlib.util.find_spec internally use PathFinder.find_spec)

YouJiacheng
  • 449
  • 3
  • 11