Relative Python imports in package are not in the way

How to import a file that is in the parent directory in a python package (which is not in the path) into a file in the child directory?

I don't quite understand the python packaging vocabulary, so as an example:

dir1/ __init__.py runner.py in_dir1.py dir2/ __init__.py in_dir2.py 

dir1 / in_dir1.py:

 def example(): print "Hello from dir1/in_dir1.example()" 

dir1 / dir2 / in_dir2.py

 import in_dir1 #or whatever this should be to make this work print "Inside in_dir2.py, calling in_dir1.example()" print in_dir1.example() 

Given that dir1 not in the python path, I am looking for a better way to import in_dir1 into in_dir2 .

I tried from .. import in_dir1 and from ..dir1 import in_dir1 based on this Q / A , but it doesn't work. What is the correct way to fulfill this intention? This Q / A seems to contain the answer; however, I'm not quite sure what to do with this / how to solve my problem using PEP 366

Both __init__.py files are empty and I'm on v2.6.

I am trying to do this without using any hacks in the way that Google continues to open.

+4
source share
2 answers

The answer is indicated in the link you provided:

Relative imports use the module __name__ attribute to determine what module positions are in the package hierarchy. If the module name does not contain any information about the package (for example, it is set to " main "), then relative import is allowed, as if the module was the top level module, regardless of where the module is actually located in the system file.

You cannot perform relative imports in __main__ scripts (i.e., when python in_dir2.py run python in_dir2.py ).

To solve this problem, PEP 366 allows you to install global __package__ :

 import dir1 if __name__ == '__main__': __package__ = 'dir1.dir2' from .. import in_dir1 

Note that the dir1 package should still be on sys.path ! You can manipulate sys.path to achieve this. But by the time that you have achieved absolute imports?

+2
source

You can really do this:

 import sys sys.path.append('..') 

and it will work. But do not do it. This can break other modules.

I think you can delete it immediately after import, but do not do this.

EDIT:

Actually, this also works, and I think there is no reason that it was not safe:

inside in_dir2.py you can do:

 import sys import os current_module = sys.modules[__name__] indir2file=current_module.__file__ sys.path.append(os.path.dirname(os.path.abspath(indir2file))+os.sep+".."+os.sep) import in_dir1 

Try restructuring your code.

0
source

Source: https://habr.com/ru/post/1393059/


All Articles