2010-12-08 1 views
559

У меня есть следующая структура папок.Импорт файлов из другой папки

application/app/folder/file.py

, и я хочу, чтобы импортировать некоторые функции из file.py в другом файле Python, который проживает в

application/app2/some_folder/some_file.py

Я попытался

from application.app.folder.file import func_name

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

+0

Родственный: http://stackoverflow.com/q/43476403/674039 – wim 2017-04-18 15:56:55

ответ

691

По умолчанию вы не можете. При импорте файла Python ищет только текущий каталог, каталог, из которого выполняется сценарий начальной точки, и sys.path, который включает в себя такие места, как каталог установки пакета (это на самом деле немного сложнее, чем это, но это касается большинства случаев).

Однако, вы можете добавить к пути Python во время выполнения:

# some_file.py 
import sys 
sys.path.insert(0, '/path/to/application/app/folder') 

import file 
+150

`sys.path.append ('/ путь/к/приложение/приложения/папки') `is cleaner imo – pseudosudo 2011-09-01 21:48:33

+218

@pseudosudo: Да, это так, но вставка его в начале имеет преимущество, гарантирующее, что поиск пути выполняется перед другими (даже встроенными) в случае конфликтов имен. – Cameron 2011-09-02 02:47:33

+0

Теперь, если только у Python `lists` был метод` preend`, так что лучший выбор не был бы уродливым. Я понимаю причину, почему `preend` не существует (потому что это будет иметь худшее время выполнения, чем` append`), но, похоже, это спорная причина. Не следует ли легко читать, чтобы быть оцененным быстрее, чтобы бежать? – ArtOfWarfare 2013-10-31 18:54:56

329

Nothing неверно с:

from application.app.folder.file import func_name 

Just убедитесь, что папка также содержит __init__.py, это позволяет включать ее в комплект. Не знаю, почему другие ответы говорят о PYTHONPATH.

14

Из того, что я знаю, добавьте файл __init__.py непосредственно в папку функций, которые вы хотите импортировать, выполнит эту работу.

12

application Учитывая, как корневой каталог для вашего питона проекта, создайте пустой файл __init__.py в application, app и folder папки. Затем в some_file.py сделать следующие изменения, чтобы получить определение FUNC_NAME:

import sys 
sys.path.insert(0, r'/from/root/directory/application') 

from application.app.folder.file import func_name ## You can also use '*' wildcard to import all the functions in file.py file. 
func_name() 
5

Если цель загрузки модуля из конкретного пути, чтобы помочь вам в процессе разработки пользовательского модуля, вы можете создать символическую ссылку в той же папке тестового скрипта, которая указывает на корень настраиваемого модуля. Эта ссылка на модуль будет иметь приоритет над любыми другими модулями, установленными с тем же именем для любого сценария, запущенного в этой папке.

Я тестировал это на Linux, но он должен работать в любой современной ОС, поддерживающей символические ссылки.

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

10

Это работает для меня на окнах

# some_file.py on mainApp/app2 
import sys 
sys.path.insert(0, sys.path[0]+'\\app2') 

import some_file 
11

работал для меня в Python3 на Linux

import sys 
sys.path.append(pathToFolderContainingScripts) 
from scriptName import functionName #scriptName without .py extension 
25

Когда модули находятся в параллельных местах, как и в вопросе:

application/app2/some_folder/some_file.py 
application/app2/another_folder/another_file.py 

Эта стенограмма делает один модуль видимым для другого:

import sys 
sys.path.append('../') 
5

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

Для этого изменить:

from application.app.folder.file import func_name

к этому:

from .application.app.folder.file import func_name 

Добавляя точку вы говорите посмотрите в эту папку для папки приложения вместо того, чтобы смотреть в Python.

(Hope это фиксирует вашу проблему!)

-1
sys.path.insert(0, '/path/to/application/app/folder') 
3

Я совершенно особенное: Я использую Python с Windows!

Я только что закончил информацию: как для Windows, так и для Linux, как относительная, так и абсолютная работа пути в sys.path (Мне нужны относительные пути, потому что я использую свои сценарии на нескольких ПК и в разных основных каталогах).

А при использовании Windows, как \ и / может быть использован в качестве разделителя для имен файлов и, конечно, вы должны удвоить \ в строки Python,
некоторых действительные примеров:

sys.path.append('c:\\tools\\mydir') 
sys.path.append('..\\mytools') 
sys.path.append('c:/tools/mydir') 
sys.path.append('../mytools') 

(примечание: Я считаю, что / более удобен, чем \, если он меньше «Windows-native», потому что он совместим с Linux и проще писать и копировать в Windows Explorer)

0

Вы можете r efresh оболочку Python, нажав f5 или перейдите в Run-> Run Module. Таким образом, вам не нужно менять каталог, чтобы что-то прочитать из файла. Python автоматически изменит каталог. Но если вы хотите работать с разными файлами из разных каталогов в Python Shell, вы можете изменить каталог в sys, as Cameron said раньше.

1

Использование sys.path.append с абсолютным путем не является идеальным при перемещении приложения в другие среды. Использование относительного пути не всегда будет работать, потому что текущий рабочий каталог зависит от того, как работает скрипт.

Поскольку структура папок приложения исправлена, мы можем использовать os.path для получения полного пути.Например, если это структура:

/home/me/application/app2/some_folder/vanilla.py 
/home/me/application/app2/another_folder/mango.py 

И давайте предположим, что вы хотите импортировать модуль «манго». Вы можете сделать следующее в vanilla.py:

import sys, os.path 
mango_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) 
+ '/another_folder/') 
sys.path.append(mango_dir) 
import mango 

Конечно, вам не нужно переменную mango_dir.

Чтобы понять, как это работает смотрит на этой интерактивной сессии, например:

>>> import os 
>>> mydir = '/home/me/application/app2/some_folder' 
>>> newdir = os.path.abspath(os.path.join(mydir, '..')) 
>>> newdir 
    '/home/me/application/app2' 
>>> newdir = os.path.abspath(os.path.join(mydir, '..')) + '/another_folder' 
>>> 
>>> newdir 
'/home/me/application/app2/another_folder' 
>>> 

и проверьте документацию os.path.

0

В моем случае у меня был класс для импорта. Мой файл выглядит следующим образом:

# /opt/path/to/code/log_helper.py 
class LogHelper: 
    # stuff here 

В моем главном файле я включил код через:

path.append("/opt/path/to/code/") 
from log_helper import LogHelper 
0

Try относительно импорта Питона:

from ...app.folder.file import func_name 

Каждой ведущей точкой является еще более высоким уровнем в иерархия, начинающаяся с текущего каталога.


Проблемы? Если это не работает для вас, вы, вероятно, получаете немного из-за относительного импорта. Читайте ответы и комментарии для более подробной информации: How to fix "Attempted relative import in non-package" even with __init__.py

Подсказка: есть __init__.py на каждом уровне каталога. Вам может понадобиться python -m application.app2.some_folder.some_file (оставляя .py), который вы запускаете из каталога верхнего уровня или имеете этот каталог верхнего уровня в PYTHONPATH. Фу!

4

ответы здесь не хватает ясности, это проверено на Python 3.6

с этой структурой папок:

main.py 
| 
---- myfolder/myfile.py 

где myfile.py имеет содержание:

def myfunc(): 
    print('hello') 

оператором импорта в main.py является:

from myfolder.myfile import myfunc 
myfunc() 

и отпечатывается привет