Использовать __init__.py для изменения пути sys - это хорошая идея? - PullRequest
0 голосов
/ 26 сентября 2018

Я хочу попросить вас кое-что, что пришло мне в голову, делать что-то.

У меня есть следующая структура:

src
    - __init__.py
    - class1.py
    + folder2
        - __init__.py
        - class2.py

I class2.py Я хочу импортировать class1 для использованияЭто.Очевидно, я не могу использовать

from src.class1 import Class1

, потому что это приведет к ошибке.Обходной путь, который мне подходит, это определить следующее в __init__.py внутри folder2:

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

Мой вопрос: допустим ли этот параметр и хорошая ли идея для использования, или, может быть, есть лучшие решения?.

Другой вопрос .Представьте себе, что структура проекта:

src
    - __init__.py
    - class1.py
    + folder2
        - __init__.py
        - class2.py
    + errorsFolder
        - __init__.py
        - errors.py

В class1:

from errorsFolder.errors import Errors

, это работает отлично.Но если я попытаюсь сделать это в class2, который находится на том же уровне, что и errorsFolder:

from src.errorsFolder.errors import Errors

Не получится (ImportError: No module named src.errorsFolder.errors)

Заранее спасибо!

Ответы [ 5 ]

0 голосов
/ 26 сентября 2018

По моему мнению, структура вашего проекта должна быть такой, что вам никогда не потребуется импортировать class1 в ваш class2 в соответствии с текущей структурой проекта.Если ваш class1 - это какая-то утилита, которую можно использовать в любом месте проекта, вы можете создать пакет для таких вещей.

Вы можете проверить эту статью на среде, чтобы создать пакет

В противном случае ..class1 также является опцией, но обычно изменение пути sys не является хорошей идеей.

Спасибо.

0 голосов
/ 26 сентября 2018

Несмотря на то, что импортировать «родительский» модуль в ваш пакет немного шокирует, ваш обходной путь зависит от текущей директории, в которой вы запускаете приложение, и это плохо.

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

должно быть

import sys,os
sys.path.append(os.path.join(os.path.dirname(__file__),os.pardir))

, чтобы добавить родительский каталог каталога вашего текущего модуля, независимо от текущего каталога, из которого вы запускаете приложение (ваш модуль может быть импортирован несколькими приложениями, которые невсе должны быть запущены в одном каталоге)

0 голосов
/ 26 сентября 2018

from ..class1 import Class1 должно работать (по крайней мере, здесь, в похожем макете, используя python 2.7.x).

Как правило: использование `sys.path 'обычно очень плохая идея, особенно если это позволяет импортировать один и тот же модуль по двум разным путям (что было бы в случае с макетом ваших файлов).

Кроме того, вы можете дважды подумать о вашем текущем макете.Python не является Java и не требует (и даже не поощряет) подход «один класс на модуль».Если оба класса должны работать вместе, они могут быть лучше в одном и том же модуле или, по крайней мере, в модулях одного уровня в дереве пакетов (обратите внимание, что вы можете использовать пакет верхнего уровня __init__как фасад для обеспечения прямого доступа к объектам, определенным в подмодулях / подпакетах).NB: Я не говорю, что ваш текущий макет обязательно неправильный, просто он может не быть самым простым.

0 голосов
/ 26 сентября 2018

Нет, это не хорошо.Python принимает модули двумя способами:

  1. Python ищет свои модули и пакеты в $ PYTHONPATH.См .: https://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH

Чтобы узнать, что входит в $ PYTHONPATH, запустите следующий код в python (3):

import sys print(sys.path)

все папки, содержащие init .py, помечены как пакет python (если они являются подкаталогами в PYTHONPATH)

С помощью этих двух способов вы можете полностью заполнитьнеобходимо создать проект Python.

0 голосов
/ 26 сентября 2018

Один правильный способ решить эту проблему - установить переменную окружения PYTHONPATH на путь, содержащий src.Тогда import src.class1 всегда будет работать, независимо от того, в каком каталоге вы начинаете.

...