Импортировать файл по пути, указанному пользователем - PullRequest
2 голосов
/ 21 декабря 2011

Я пишу тестер, который запускает пользовательские скрипты:

tester d:\scripts\test_scripts_list.txt

test_scripts_list.txt выглядит так:

test1
d:\123\test2

Моя программа читает командную строку с argparse *Модуль 1008 *, читает каждую строку test_scripts_list.txt и импортирует каждый тестовый файл с __import__ (который фактически запускает тестовый файл).
Это работает хорошо.

Моя единственная проблема - импортировать d: \ 123 \ test2 это дает мне:

ImportError: Import by filename is not supported.

Я думаю, что это можно решить, проанализировав имя пути, добавив его в PYTHONPATH при работе с sys.path.append ичем импортировать это.Но это кажется сложной мыслью.
У вас есть идея получше?

Примечание: путь test1 уже находится в PYTHONPATH

РЕДАКТИРОВАТЬ Мое текущее решение:

# Go over each line in scripts_filename and import all tests
for line in open(scripts_file.scripts_filename):
    line = line.strip()

    if not line or  line[0] == '#':
        # Ignore empty line and line with comment
        continue
    elif line[1] == ':' and  line[2] == '\\':
        # Find the last position of '\\'
        file_name_pos =  line.rfind('\\')
        # Separate file path and filename (I.E [0:5] will take 4 first chars and [4:] will take all chars except the 4 chars)
        file_path_string =  line[0:file_name_pos+1]
        file_name_string =  line[file_name_pos+1:]
        # Append file_path_string to PYTHONPATH in order to import it later
        sys.path.append(file_path_string)

        import_name  =  file_name_string
    else:
        import_name =  line

    try:
        # Try to import test
        print  "Run test : %s" % line
        __import__(import_name)
    except ImportError:
        print "Failed! (Test not found). Continue to the next test"

1 Ответ

3 голосов
/ 21 декабря 2011

См. imp модуль , в частности функции imp.load_module и imp.load_source.Вот один из способов их использования (из исходного кода Mercurial , слегка упрощенный):

def loadpath(path):
    module_name = os.path.basename(path)[:-3]
    if os.path.isdir(path):
        # module/__init__.py style
        d, f = os.path.split(path.rstrip('/'))
        fd, fpath, desc = imp.find_module(f, [d])
        return imp.load_module(module_name, fd, fpath, desc)
    else:
        return imp.load_source(module_name, path)
...