import main file (not another module) from

2019-08-17 12:36发布

问题:

I want to import "main" from a subfolder. Therefore every subfolder contains a __init__.py (but not "source", and its actual name is "Tracks Comparer"). My folders structure is like this:

source\
  GPX\
    engine.py  (contains Engine class)
  main.py
    from GPX.engine import Engine
  Tests\
    Integration Tests\
      GPX\
        engineTest.py
      mainTest.py

I want use "main" from mainTest.py, so I tried:

from ... import main 

but it does'n work. Error: Attempted relative import in non-package

I use Visual Studio and with "Test Explorer" all tests run except for mainTest.py. For example in engineTest.py there is:

from GPX.engine import Engine

and not something like this:

from ...GPX.engine import Engine   # this not works

and in mainTest.py the simple import main works too.

To be more exact launching tests with Visual Studio works also for mainTest, BUT the import of Engine from GPX.engine fails (Error: engine module not found), I imagine because it refers to the GPX folder in the "Tests" folder. For these reasons, I think the unittest.run() is "called" from root (source folder) when Visual Studio launch tests.

To solve the problem I want to use relative paths (in tests files), but it doesn't work, as I said.

What's wrong in my relative path import? Is this the right way for doing the job? I'm using Python 2.7.


Solution for Attempted relative import in non-package: (in mainTest.py)

import os, sys
sys.path.append(os.path.join("..", ".."))
import main

Solution for engine module not found: (in mainTest.py)

#sys.path.append(os.path.join("..", ".."))
sys.path.insert(0, os.path.join("..", ".."))   
# <-- this change set "source" earlier than "Integration Tests" in path.

回答1:

Assuming you are currently in Integration Tests folder? What about this:

from os import path
import sys
currentDirectory = path.dirname(__file__)
sys.path.append(path.join(currentDirectory, '../../')) # This will get you to source
import main


回答2:

Relative imports don't work at the file system level, so what you want to do can't be done with relative imports as you described.

It sounds like you are having issues with implicit relative imports (in mainTest when you import GPX it implicitly imports .GPX instead of GPX as a root module). You can turn off this behavior by adding this line at the top of all your test files:

from __future__ import absolute_import

This will make python import GPX from sys.path instead of .GPX.