Я использую Python 2.5.
Вот дерево моих папок:
ptdraft/
nib.py
simulations/
life/
life.py
(У меня также есть __init__.py
в каждой папке, здесь опущен для удобства чтения)
Как мне импортировать модуль nib
из модуля life
? Я надеюсь, что это можно сделать без вмешательства в sys.path.
Примечание: Основной запускаемый модуль находится в папке ptdraft
.
Можно использовать относительный импорт (python >= 2.5):
from ... import nib
(Что нового в Python 2.5) PEP 328: Абсолютный и относительный импорт
EDIT: добавлена еще одна точка '.' для перехода к двум пакетам
Относительный импорт (как в из импорт .. библиотека mymodule`) работает только в пакете. Чтобы импортировать 'библиотека mymodule' то есть в родительский каталог текущего модуля:
import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir)
import mymodule
редактировать: атрибут `file, что не всегда дается. Вместо использования ОС.путь.abspath(file, что) теперь я предложил использовать модуль проверьте, чтобы извлечь имя файла (и путь) текущего файла
Похоже, что проблема не связана с тем, что модуль находится в родительском каталоге или что-то в этом роде.
Вам нужно добавить каталог, содержащий ptdraft
в PYTHONPATH
Вы сказали, что import nib
у вас работает, это вероятно означает, что вы добавили сам ptdraft
(не его родителя) в PYTHONPATH.
Я отвечал на подобный ответ также на вопрос относительно импорта из одноуровневых пакеты. Вы можете увидеть здесь. Следующие испытания с Python 3.6.5, (Анаконда, стадион conda 4.5.1), Windows 10 на устройстве.
Я предполагаю, что такую же структуру папок, как в вопросе
.
└── ptdraft
├── __init__.py
├── nib.py
└── simulations
├── __init__.py
└── life
├── __init__.py
└── life.py
Я называю .
корневая папка, а в моем случае она находится в C:\tmp\test_imports`.
Содержание `setup.py может быть просто
from setuptools import setup, find_packages
setup(name='myproject', version='1.0', packages=find_packages())
В основном "по любому" и setup.py будет работать. Это всего лишь минимальный рабочий пример.
Если вы знакомы с виртуальными средами, активировать одну, и переходите к следующему шагу. Использование виртуальных сред не абсолютно обязательные, но они реально вам поможет в долгосрочной перспективе (когда у вас более 1 проекта продолжается..). Самые элементарные действия (запустить в корневой папке)
питон -м venv venv
. /venv/bin/активировать
(Linux) или ./venv/Скрипты/активировать
(победа)Чтобы узнать больше об этом, просто Google из на "Виртуального питона ОКР учебник" или подобные. Вы, наверное, не нужны никакие другие команды, чем создание, активация и деактивация.
После того как вы сделали и активированные виртуальной среде, ваша консоль должна дать название виртуальной среде в скобках
PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>
Установить мой проект вашего высокоуровневый пакет `через
типун. Хитрость заключается в том, чтобы использовать флаг
-е` при выполнении установки. Таким образом, он устанавливается в редактируемом состоянии, и все изменения внесены .пы файлы будут автоматически включены в пакет.
В корневой каталог, выполнить
типун установите -е
. (обратите внимание на точку, оно означает "в текущем каталоге и")
Вы также можете увидеть, что он установлен с помощью замораживания Пип`
(venv) PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
Running setup.py develop for myproject
Successfully installed myproject
(venv) PS C:\tmp\test_imports> pip freeze
myproject==1.0
mainfolder
для каждого импортаВ этом примере mainfolder
будет ptdraft
. Это имеет то преимущество, что вас не будет конфликта имен с другими именами модуль (из стандартной библиотеки Python или 3-й партии модулей).
def function_from_nib():
print('I am the return value from function_from_nib!')
from ptdraft.nib import function_from_nib
if __name__ == '__main__':
function_from_nib()
(venv) PS C:\tmp\test_imports> python .\ptdraft\simulations\life\life.py
I am the return value from function_from_nib!
Если добавление папки вашего модуля в PYTHONPATH не помогло, вы можете изменить список sys.path в вашей программе, в котором интерпретатор Python ищет модули для импорта, говорится в документации python:
Когда импортируется модуль с именем spam, интерпретатор сначала ищет встроенный модуль с таким именем. Если он не найден, то ищет файл с именем spam.py в списке каталогов, заданном переменной sys.path. sys.path инициализируется из этих мест:
- каталог, содержащий входной скрипт (или текущий каталог).
- PYTHONPATH (список имен каталогов, с тем же синтаксисом, что и переменная shell PATH).
- значение по умолчанию, зависящее от установки.
После инициализации программы Python могут изменять sys.path. Каталог, содержащий запускаемый скрипт, помещается в начало пути поиска, впереди пути стандартной библиотеки. Это означает, что скрипты в этом каталоге будут загружены вместо одноименных модулей в каталоге библиотеки. Это ошибка, если только замена не является целевой.
Зная это, вы можете сделать в своей программе следующее:
import sys
# Add the ptdraft folder path to the sys.path list
sys.path.append('/path/to/ptdraft/')
# Now you can import your module
from ptdraft import nib
# Or just
import ptdraft
Вы можете использовать в зависимости от операционной системы путь в "модуль поиска пути" и которая указана в . sys файла.путь . Так что вы можете легко добавить родительский каталог, как следующие
import sys
sys.path.insert(0,'..')
Если вы хотите добавить Родительский-родительский каталог
sys.path.insert(0,'../..')
Дон'т много знаю о Python 2.<БР /> В Python 3, родительской папки могут быть добавлены следующим образом:
import sys
sys.path.append('..')
...а затем вы сможете импортировать модули из него
Вот ответ, что'ы проста, так что вы можете увидеть, как это работает, малого и кросс-платформенный.
Он только использует встроенные модули (ОС
, пакет sys
и проверить
), так что должно работать
в любой операционной системе (ОС), так как Python предназначен для этого.
в
from inspect import getsourcefile
import os.path as path, sys
current_dir = path.dirname(path.abspath(getsourcefile(lambda:0)))
sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)])
import my_module # Replace "my_module" here with the module name.
sys.path.pop(0)
Меньше линий, чем это заменить вторую строку с импортом ОС.путь как путь, Сыс, проверять, добавить осмотреть.
в начале getsourcefile
(линия 3) и удалите первую строку.
в
from inspect import getsourcefile
import os.path
import sys
current_path = os.path.abspath(getsourcefile(lambda:0))
current_dir = os.path.dirname(current_path)
parent_dir = current_dir[:current_dir.rfind(os.path.sep)]
sys.path.insert(0, parent_dir)
import my_module # Replace "my_module" here with the module name.
Он использует пример переполнения стека ответа Как я могу получить путь к текущей выполненный файл в Python? Найти источник (именем) на выполнение кода с помощью встроенного инструмента.
от проверить импорт getsourcefile от ос.импорт путь abspath рядом, везде, где вы хотите, чтобы найти исходный файл из вы просто использовать:
abspath(getsourcefile(лямбда:0))
Мой код добавляет путь к файлу `Сыс.путь в список пути Python потому что это позволяет Python, чтобы импортировать модули из этой папки.
После импорта модуля в код, это's не хорошая идея, чтобы запустить пакет `sys.путь.поп(0) на новую строку когда добавил папку модуль с таким же именем в другом модуле, который импортируется позже в программе. Вам нужно удалить элемент списка добавляется до импорта, а не другие пути. Если ваша программа не'т импортировать другие модули, он's, можно не удалить путь к файлу, потому что после того, как программа закончится (или перезапуск оболочки Python), любые изменения, сделанные к таблице sys.путь исчезнет.
Мой ответ Не'т использовать переменную файл____`, чтобы получить путь к файлу/имя работает код, потому что здесь пользователи часто описывают его как неблагонадежных. Вы должны'т использовать его для импортировать модули из родительской папки в программах использованы другими людьми.
Некоторые примеры, где это не't работа (цитата из этого переполнение стека вопрос):
• он может'т быть На некоторых платформах • иногда это'т полный путь к файлу
py2exe
не't имеют атрибут файла____`, но существует обходной путь- при запуске от простоя с
выполнить()
нет__файл__
атрибут- ОС Х 10.6, где я получаю NameError: глобальное имя 'файл' не определен`
Я нашла такой способ работает для импорта пакет из сценария'родительской директории. В примере, я хотел бы, чтобы импортировать функции в env.py
из приложения.пакет БД
.
. └── my_application └── перегонный куб env.py └── └── приложение ├── __init__.py └── дБ
импорт ОС импорт Сыс currentdir = ОС.путь.каталог(ОС.путь.реального пути(__Файл__)) parentdir = ОС.путь.каталог(currentdir) Сыс.путь.присоеденить(parentdir)
Для меня самый короткий и мой любимый, проявляющаяся для доступа к родительской директории:
sys.path.append(os.path.dirname(os.getcwd()))
или:
sys.path.insert(1, os.path.dirname(os.getcwd()))
ОС.функция getcwd() возвращает имя текущего рабочего каталога, ОС.путь.каталог(параметра directory_name) возвращает имя директории, в которой прошел один.
На самом деле, на мой взгляд архитектура проекта Python должно быть сделано так, где ни один модуль из каталога ребенок будет использовать любой модуль из родительского каталога. Если что-то подобное происходит, стоит переосмыслить о дереве проекта.
Другой способ-добавить папку в PYTHONPATH переменной системного окружения.
импорт Сыс Сыс.путь.добавить('../')
Когда не будучи в пакете среде с __init__.py
файлы pathlib библиотека (в комплекте с >= в Python 3.4) дает очень лаконичный и понятный, чтобы добавить путь к директории с PYTHONPATH:
import sys
from pathlib import Path
sys.path.append(str(Path('.').absolute().parent))
Вышеуказанными решениями тоже все в порядке. Другое решение этой проблемы
Если вы хотите что-либо импортировать из корневой директории. Затем,
from ...module_name import *
Также, если вы хотите импортировать любой модуль из родительского каталога. Затем,
from ..module_name import *
Также, если вы хотите импортировать любой модуль из родительского каталога. Затем,
from ...module_name.another_module import *
Таким образом, вы можете импортировать какой-либо конкретный метод, если вы хотите.
Работа с библиотеками. Сделать библиотеку под названием наконечник, установите его с помощью setup.py пусть живут на сайте-пакеты решены и ваши проблемы. Вы Don'т иметь, чтобы запихнуть все в один пакет. Разбить его на куски.
В системе Linux, вы можете создать мягкую ссылку из "Жизнь" в папке с файлом nib.py . Затем, вы можете просто импортировать его как:
import nib
Простое решение для абсолютного пути в Windows 10:
import sys
sys.path.insert(0,'C:\\Users\\user01\\Desktop\\pipeline')
from folder1.folder2.filename import function_name
это будет импортировать функции и"имя_функции-то" от: C:\Users\user01\Desktop\pipeline\folder1\folder2\filename