Как импортировать каталог с модулями в путь Python, который является символической ссылкой на исходный источник из подпапки?

Я пытаюсь запустить докер-контейнеры child1 и child2. скажем, у нас есть:

ОБНОВЛЕНО

|parent
|-----|child1/
             src_folder/
                       __init__.py
                       mod1.py
|-----|child2/
            __init__.py
            symlink_target_folder
            mody.py
            test1_dir/
                      smfile.py

Я сделал что-то вроде

ln -rs ~/parent/child1/src_folder ~/parent/child2/symlink_target_folder

В mody.py Когда я это делаю,

from symlink_target_folder import mod1

оно работает;

но из test1_dir>smfile.py, когда я это делаю

from .child2.symlink_target_folder import mod1

он возвращает ImportError.

Я хочу знать, как я могу получить доступ к тому же модулю из этого каталога? Может ли экспорт symlink_target_folder в PYTHONPATH как-то сработать. я сделал

экспортировать PYTHONPATH=$PYTHONPATH:/symlink_target_folder

так что ` я могу сделать из mody.py

from symlink_target_folder.mod1 import SmFoo

но я не думаю, что это связано с PYTHONPATH. просто symlink_target_folder и mody.py находятся в одной папке.

Как мне это решить? Как лучше подойти к этой проблеме? Я проверил это


person user2290820    schedule 03.04.2015    source источник
comment
Чтобы быть уверенным в том, о чем вы спрашиваете: проблема в том, что скрипт выдает ImportError, когда вы пытаетесь выполнить smfile.py в каталоге test1_dir с помощью команды python smfile.py, верно?   -  person FunkySayu    schedule 06.04.2015
comment
как cd child2/test1_dir/ && python smfile.py верно?   -  person FunkySayu    schedule 06.04.2015
comment
@FunkySayu Если я экспортировал конкретный каталог в pythonpath, скажем, в папку X, могу ли я сделать From X import * из подпапки? в данном случае это будет test1_dir, потому что он не работает;   -  person user2290820    schedule 06.04.2015
comment
@FunkySayu Если я экспортировал конкретный каталог в pythonpath, скажем, в папку X, могу ли я сделать From X import * из подпапки? в данном случае это будет test1_dir, потому что он не работает;   -  person user2290820    schedule 06.04.2015
comment
Ответ обновлен. Проверено, работает.   -  person FunkySayu    schedule 07.04.2015


Ответы (2)


Итак, у вас есть следующий результат дерева:

.
├── child1
│   └── srcFolder
│       ├── __init__.py
│       ├── __init__.pyc
│       ├── mod1.py
│       └── mod1.pyc
└── child2
    ├── __init__.py
    ├── mody.py
    ├── symlink_target_folder -> ../child1/srcFolder
    └── test1_dir
        ├── __init__.py
        └── smFile.py

Если вы поместите следующие заголовки в свой smFile.py, импорт будет работать:

import sys
import os

sys.path.append(os.path.abspath(os.sep.join([".."])))

from symlink_target_folder import mod1

mod1.foo()

Вместо использования символической ссылки вы также можете использовать этот способ для добавления пути:

sys.path.append(os.path.abspath(os.sep.join(["..", "..", "child1", "srcFolder"])))
person FunkySayu    schedule 03.04.2015
comment
Символические ссылки являются обязательным требованием. Я хочу знать, есть ли способ сделать это с помощью символических ссылок? - person user2290820; 03.04.2015
comment
Вы пробовали from symlink_target_folder.md1 import SmFoo ? - person FunkySayu; 03.04.2015
comment
Вот где я застрял. Интересно, почему он выдает ImportError: No module named symlink_target_folder.md1; я запускаю скрипт bash, который сначала экспортирует этот символический путь в PYTHONPATH. все равно выдает ошибку. не уверен, правильно ли он экспортируется. - person user2290820; 03.04.2015
comment
Я не понимаю вашей проблемы: я пробовал с cd child2 && ln -s ../child1 child1, и он работает правильно. - person FunkySayu; 03.04.2015
comment
Я обновил вопрос. Не могли бы вы пересмотреть его еще раз? - person user2290820; 05.04.2015
comment
Смотрите комментарии к вопросу - person FunkySayu; 06.04.2015
comment
новое редактирование такое же, как из ..symlink_target_folder import mod1, верно? - person user2290820; 07.04.2015
comment
Я также ищу более универсальный способ, поэтому я искал экспорт в Pythonpath. похоже, когда я экспортирую pythonpath=$pythonpath:/folder_name; я до сих пор не могу сделать импорт из имени_папки * глубоко из подпапок.. - person user2290820; 07.04.2015
comment
Я действительно не рекомендую использовать переменные среды для решения вашей проблемы. Все, что вы можете сделать на Python, делайте на Python. Кроме того, использование символических ссылок — не лучшее, что вы можете сделать. Кстати, если вы хотите автоматически сгенерировать трюк sys.path (как вы сказали, более универсальный способ), оформите buildout для Python. Plone, например, представляет собой большой проект, основанный на этом, с несколькими модулями, и он автоматически генерирует стартовые сценарии. - person FunkySayu; 07.04.2015
comment
хм, сборка отвечает всем требованиям, но я ищу легкий встроенный механизм. Недавно я узнал о pkgutil и задал здесь соответствующий вопрос: stackoverflow.com/questions/29471039/ Итак, если я понимаю, как работает pkgutil, может это решит все проблемы! - person user2290820; 07.04.2015

Вот как я решил эту проблему;

Данный

|parent
|-----|child1/
             src_folder/
                       __init__.py
                       mod1.py
|-----|child2/
            __init__.py
            symlink_target_folder
            mody.py
            test1_dir/
                      smfile.py

я создал somepth.pth в файле child2, который имеет это:

symlink_target_folder

Затем simplepth.py под скриптом child2 выглядит следующим образом:

import site
import os

site.addsitedir(os.path.dirname(__file__))

Когда вы запускаете child2>simplepth.py, он добавит каталог, в котором находится simplepth, и любой файл .pth, который естественным образом указывает на /child1/srcFolder, и импортирует его в sys.path.

теперь вы можете просто сделать:

import mod1

который решает мою проблему.

поэтому, если вы хотите запустить только test1_dir/smFile.py, вы можете просто добавить родительский каталог test1_dir и добавить его в site.addsitedir, а затем импортировать mod1, и он будет работать.

person Community    schedule 09.04.2015