PYTHONPATH Application

I have an application with a package hierarchy. There are many modules that reference other modules above in the package hierarchy. As shown below, I can use relative imports to solve this problem. However, the launch of the module directly for testing ends with the exception of Attempted relative import in non-package .

Is there a better way to organize my application or my import statements so that the modules can be run separately for testing and importing from other modules?

Example

 \spam \morespam child.py base.py \eggs user.py 

base.py

 class Base(object): def hello(self): print 'Um, wot?' 

child.py

 from ..base import Base # references the parent package correctly, # but fails when this module is executed individually class Child(Base): def hello(self): print 'Hello, world!' if __name__ == '__main__': import unittest # ... unit test code ... 

user.py

 from spam.morespam.child import Child print Child().hello() 

Existing solution

I found that I can add the following header to the top of the module, which should refer to the modules above in the hierarchy:

 if __name__ == '__main__': import sys, os sys.path.append(os.path.abspath(os.path.join(sys.path[0], '..'))) 

The disadvantage is that I need to add this code everywhere, and it is not constant: the relative path '..' varies depending on the depth of the packet in the hierarchy.

Other possible solutions ...

  • I could create a .pth file with my application root. Unfortunately, this must be added to the package site folder of my Python installation, so it is not very application specific.
  • I could temporarily add my application root directory to PYTHONPATH and make all my modules link packages from the root. This eliminates the ease of running the script by simply calling python.exe whatever.py .
  • I could write some module that, when importing, will look for a marker file in the root folder of my application. This common module could then be installed on my local Python installation and imported by each module in my application, thereby ensuring that the root directory is in PYTHONPATH, regardless of which module I execute.
+4
source share
2 answers

I solved this with PyCharm, which automatically adds my source root to PYTHONPATH every time it launches my application. As far as I can tell, PyCharm basically makes option number 2 for me.

0
source

You need to add __init__.py as empty files in the folders from which you want to import. This will cause python to treat directories as packages, allowing you to use them in import statements:

 \spam \morespam __init__.py child.py __init__.py base.py \eggs __init__.py user.py 

Once you do this and install PYTHONPATH into the database of this directory, you can import:

base.py

 from morespam.child import Child from ..eggs import user 

While the __init__.py file should only be present in this file, you can also define the __ALL__ variable in this file as a list of modules in this directory that you want to import if you are trying to use script import * .

+1
source

All Articles