Импортировать модуль по относительному пути

Как импортировать модуль Python с учетом его относительного пути?

Например, если dirFoo содержит Foo.py и dirBar, а dirBar содержит Bar.py, как мне импортировать Bar.py в Foo.py?

Вот визуальное представление:

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Foo хочет включить Bar, но реструктуризация иерархии папок не вариант.

Может быть, похоже на stackoverflow.com/questions/72852/…?

Joril 11.11.2008 02:44

Проверьте мой ответ, он пока самый полный, другие не работают в особых случаях, например, когда вы вызываете скрипт из другого каталога или из другого скрипта python. См. stackoverflow.com/questions/279237/…

sorin 26.05.2011 10:17

У меня была аналогичная проблема, я нашел это, и он работает !! apt-get установить python-profiler

ldcl289 23.09.2011 00:18

На всякий случай, если кто-то захочет сделать это статически и попадет сюда (как я :), вы также можете настроить переменную среды PYTHONPATH

okaram 11.01.2015 00:23

Лучше следовать инструкциям в Lib / site.py для каждого случая.

Avenida Gez 01.04.2015 18:15
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
774
5
909 530
22
Перейти к ответу Данный вопрос помечен как решенный

Ответы 22

Убедитесь, что в dirBar есть файл __init__.py - это превращает каталог в пакет Python.

Обратите внимание, что этот файл может быть полностью пустым.

Harley Holcombe 11.11.2008 01:00

Если родительский каталог dirBar не находится в sys.path, то присутствие __init__.py в каталоге dirBar не очень помогает.

jfs 11.11.2008 01:40

Приведенный выше комментарий предполагает, что dirBar является подпакетом.

jfs 11.11.2008 02:11

-1, добавление __init.py__ будет работать только тогда, когда каталог уже находится в sys.path, а в моем случае это не так. Решение по «сорину» (принятое) всегда работает.

Czarek Tomczak 23.11.2011 03:27

"когда каталог уже находится в sys.path". Хотя это абсолютно верно, как мы могли догадаться, что каталога не было в sys.path из вопроса? Возможно, было что-то упущено, чего мы не видели или о чем не знали?

S.Lott 23.11.2011 04:47

Дополнительный контекст: __init__.py - это просто токен, который сообщает Python, что вы действительно хотите иметь возможность использовать папку с import (по умолчанию «нет», чтобы предотвратить случайное повреждение пространства имен).

Brent Bradburn 20.12.2012 05:32

Хотя это не обязательно идеальное решение во всех случаях, оно очень хорошо работает для таких целей, как организация модулей. Спасибо!

Tiffany 16.02.2015 05:53

Это отнюдь не означает ответ на вопрос: существует ли файл инициализации или нет, это не заставляет python заглядывать в подкаталоги. Как он получил сотни положительных голосов?

gented 03.04.2017 19:15

Если вы структурируете свой проект таким образом:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

Затем из Foo.py вы сможете:

import dirFoo.Foo

Или же:

from dirFoo.Foo import FooObject

Согласно комментарию Тома, для этого требуется, чтобы папка src была доступна либо через site_packages, либо через ваш путь поиска. Кроме того, как он упоминает, __init__.py неявно импортируется, когда вы впервые импортируете модуль в этот пакет / каталог. Обычно __init__.py - это просто пустой файл.

Также отметьте, что в этом.py импортируется, когда импортируется первый модуль внутри этого пакета. Кроме того, ваш пример будет работать только в том случае, если src находится в site_packages (или в пути поиска)

Tom Leys 11.11.2008 01:00

Это самое простое решение, которое я искал. Если файл для импорта обязательно находится в одном из подкаталогов, это решение - жемчужина.

Deepak G M 31.12.2012 12:59

Я пробовал то же самое, но потерпел неудачу. Я не знаю почему. ImportError: нет модуля с именем customMath

Ming Li 05.03.2014 16:09

Зачем кому-то импортировать Foo из самого Foo.py? Думаю, должно быть от Bar.py.

bhaskarc 25.10.2015 23:08
from dirFoo import Foo, чтобы сказать Foo.bla(). При использовании import dirFoo.Foo следует использовать dirFoo.Foo.bla() - довольно некрасиво даже без верблюжьего футляра.
Cees Timmerman 01.11.2016 16:13

как импортировать Bar.py из Foo.py ??

lurscher 27.10.2018 23:55

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

import sys
sys.path.insert(0, <path to dirFoo>)
import Bar

Похоже, ваш ответ не работает с относительными путями, см. stackoverflow.com/questions/279237/…

bogdan 23.05.2011 18:03

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

Brent Bradburn 20.12.2012 05:11

Можно сделать что-то вроде sys.path.append(os.path.dirname(__file__) + "/relative/path/to/module")

Falko 06.11.2015 15:43

или sys.path.append(__name__ if __name__ != '__main__' else __loader__.fullname)

vim 18.01.2017 15:42

Рассмотрите возможность использования sys.path.insert(0, <path to dirFoo>), поскольку он загрузит этот модуль раньше, чем одноименные модули, хранящиеся в другом месте.

Anton Tarasenko 29.10.2017 16:33

Это соответствующий PEP:

http://www.python.org/dev/peps/pep-0328/

В частности, предположим, что dirFoo - это каталог выше dirBar ...

В dirFoo \ Foo.py:

from ..dirBar import Bar

это сработало для меня, просто добавил в этом.py в каждую папку и успешно импортировать

yussan 07.01.2018 05:29

Самый простой способ - использовать sys.path.append ().

Однако вас также может заинтересовать модуль чертенок. Он обеспечивает доступ к функциям внутреннего импорта.

# mod_name is the filename without the .py/.pyc extention
py_mod = imp.load_source(mod_name,filename_path) # Loads .py file
py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file 

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

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

Также эти функции могут быть полезны:

imp.find_module(name[, path])
imp.load_module(name, file, pathname, description)

Обратите внимание, что в документации imp.load_source и imp.load_compiled указаны как устаревшие. Вместо этого рекомендуется использовать imp.find_module и imp.load_module.

amicitas 18.10.2011 10:39

@amicitas, не могли бы вы предоставить какую-либо ссылку на это (мне это нужно, и я использую python 2.6. Я знаю, что об этом говорится в документации 2.7, но не нашел ссылки на 2.6)

0xc0de 06.08.2012 10:46

@ 0xc0de Вы можете найти этот оператор в документации для модуля imp как для Python 2.7.3, так и для Python 2.6.7. Похоже, этих функций нет даже в документации для python 3.2.

amicitas 08.08.2012 01:02

Для импорта таких исходных файлов в python 3.3 см. Импортируйте произвольный исходный файл на Python. (Python 3.3+) - 2 ответа. Спасибо, ребята, за советы.

nealmcb 04.10.2014 20:34

Добавьте файл __init__.py:

dirFoo\
    Foo.py
    dirBar\
        __init__.py
        Bar.py

Затем добавьте этот код в начало Foo.py:

import sys
sys.path.append('dirBar')
import Bar

Если dirBar уже является пакетом Python (из-за наличия dirBar/__init__.py), нет необходимости добавлять dirBar в sys.path, не так ли? Заявления import Bar от Foo.py должно хватить.

Santa 19.04.2010 03:06

На мой взгляд, лучший выбор - поместить __ init __.py в папку и вызвать файл с

from dirBar.Bar import *

Не рекомендуется использовать sys.path.append (), потому что что-то может пойти не так, если вы используете то же имя файла, что и существующий пакет python. Я не тестировал это, но это будет неоднозначно.

странно, что from dirBar.Bar import * работает, но не from dirBar.Bar import Bar. ты знаешь почему * работает? что, если бы у меня было несколько файлов в dirBar / и я хотел бы получить только несколько из них (используя метод, подобный тому, который вы разместили здесь)?

tester 24.06.2011 11:33

@tester: используйте from dirBar import Bar.

Brent Bradburn 20.12.2012 07:38

@tester это потому, что from указывает источник, а все, что находится после import, - это то, что нужно взять из этого источника. from dirBar.Bar import Bar означает «Из источника импортировать сам источник», что не имеет смысла. * означает, что "дайте мне все от источника"

FuriousFolder 02.08.2017 19:11
import os
import sys
lib_path = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'lib'))
sys.path.append(lib_path)

import mymodule

Мне это нравится, потому что у вас есть возможность подняться по каталогу.

Charles L. 11.08.2011 01:55

Вы должны использовать os.path.join() вместо соединения с помощью '/', что приведет к поломке (хромых) окон.

0xc0de 02.08.2012 10:58

Это ненадежно. Это зависит от текущего рабочего каталога, а не от каталога, в котором находится скрипт.

jamesdlin 31.01.2014 14:00

Может потребоваться добавить только в том случае, если путь еще не входит в путь. lib_path = os.path.abspath ('../ functions'), если lib_path не находится в sys.path: sys.path.append (lib_path)

Brent 15.08.2014 23:12

в ответ на @jamesdlin, объединив несколько ответов: а как насчет os.path.abspath(os.path.join(__file__,'..','lib'))?

Matthew Davis 03.01.2018 21:36

@MatthewDavis Я полагаю, что это работает, но мне кажется неправильным использовать имя файла в качестве такого каталога (а затем отбрасывать его с помощью ".."). Я лично предпочел бы сначала использовать os.path.dirname(__file__).

jamesdlin 04.01.2018 02:06

Честная оценка. Я вижу единственное преимущество подхода '..' - это сжатая цепочка: os.path.join(__file__, '..', '..', '..', 'lib') позволяет подняться на несколько уровней выше. Я полагаю, что наиболее понятным было бы: os.path.join(os.path.dirname(__file__), '..', '..', 'lib'), но это кажется излишним. Мысли?

Matthew Davis 09.01.2018 21:14

Просто сделайте простые вещи, чтобы импортировать файл .py из другой папки.

Допустим, у вас есть такой каталог:

lib/abc.py

Затем просто сохраните пустой файл в папке lib с именем

__init__.py

А затем используйте

from lib.abc import <Your Module name>

Храните файл __init__.py в каждой папке иерархии модуля импорта.

Ответ принят как подходящий

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

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

 import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # Use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if the script is called in different ways on Windows.
 # __file__ fails if someone does os.chdir() before.
 # sys.argv[0] also fails, because it doesn't not always contains the path.

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

Предупреждение! Я действительно не знаю, что происходит, когда текущий модуль находится внутри файла egg. Вероятно, это тоже не удается.

могу я получить объяснение, как это работает? У меня аналогичная проблема, и мне бы НРАВИТСЯ заставить модуль Python DIR вместо выполнения поиска

carl crott 15.01.2012 16:53

Запуская Win 7 Pro 64x и Python 2.7, я получаю несколько ошибок. 1) Мне пришлось добавить инспекцию в список импорта. 2) Первое значение [0] в кортеже - это пустая строка. Вторая, [1], показывает имя файла. Я предполагаю, что первым должен быть путь ... Есть идеи?

Adam Lewis 17.01.2012 09:38

Если вы собираетесь использовать подпапку, используйте ее следующим образом: os.path.realpath(os.path.abspath(os.path.split(inspect.‌​getfile( inspect.currentframe() ))[0]) + "/subfolder") Добавьте НЕТ подпапку перед abspath, поскольку это вызывает серьезные ошибки.

Maximilian Hils 13.07.2012 02:39

@ scr4ve вместо этого вам следует использовать os.path.join (), и вы можете добавить регистр (cmd_subfolder) непосредственно к моему ответу. Благодарность!

sorin 13.07.2012 16:32

для меня realpath уже генерирует абсолютные пути, поэтому мне не нужен abspath. Кроме того, вместо разделения можно использовать os.path.dirname, что делает индексирование [0] устаревшим. Тогда строка будет: os.path.realpath(os.path.dirname(inspect.getfile(inspect.cur‌​rentframe())))

ted 14.08.2012 11:37
inspect.currentframe() - это «деталь реализации CPython» (docs.python.org/2/library/inspect.html#inspect.currentframe‌), так что она тоже может дать сбой ...
Eric O Lebigot 10.07.2014 14:32

К каким конкретным случаям относится "файл терпит неудачу, если скрипт вызывается по-разному в Windows"?

Eric O Lebigot 10.07.2014 14:34

требует ли этот ответ обновления для Python 3.4?

Praneeth 11.06.2015 19:23

Что нужно иметь в виду при использовании модуля inspect для тех, кто может отключить сборщик мусора в своих скриптах: примечание о ссылочных циклах.

rob 07.03.2016 21:49

Люблю решение, но не pylint. Кто-нибудь знает хороший способ заставить Пилинт заткнуться?

James Puderer 24.01.2019 04:13

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

jpmc26 03.04.2019 06:41

Эта статья объясняет это лучше. realpython.com/absolute-vs-relative-python-imports - имейте в виду, что окончательный ответ может зависеть от диапазона версий Python, на которые вы ориентируетесь.

sorin 03.04.2019 09:15

Это заставило мой pytest сработать. Новая проблема: теперь mypy жалуется на несовместимый тип getfile "Optional [FrameType]"; ожидается "Union [Module, Type [Any], MethodType, FunctionType, TracebackType, FrameType, CodeType, Callable [..., Any]]"

Ollie 09.07.2020 11:15
from .dirBar import Bar

вместо:

from dirBar import Bar

на всякий случай может быть установлен другой dirBar и запутать читателя foo.py.

Я не смог сделать это в Windows. Это в Linux?

Gabriel 16.06.2013 03:56

Он будет работать из скрипта, импортирующего Foo. то есть: main.py импортирует dirFoo.Foo. Если вы пытаетесь запустить Foo.py как скрипт, это не удастся. См. stackoverflow.com/questions/72852/…

jgomo3 17.06.2013 23:23

Назовите меня слишком осторожным, но я предпочитаю делать свой более переносимым, потому что небезопасно предполагать, что файлы всегда будут в одном и том же месте на каждом компьютере. Лично у меня код сначала ищет путь к файлу. Я использую Linux, поэтому мой будет выглядеть так:

import os, sys
from subprocess import Popen, PIPE
try:
    path = Popen("find / -name 'file' -type f", shell=True, stdout=PIPE).stdout.read().splitlines()[0]
    if not sys.path.__contains__(path):
        sys.path.append(path)
except IndexError:
    raise RuntimeError("You must have FILE to run this program!")

Это, конечно, если вы не планируете упаковывать их вместе. Но в таком случае вам все равно не нужны два отдельных файла.

Файлы всегда будут находиться в одном и том же месте на всех компьютерах с указанием относительного пути.

Sagar Hatekar 18.12.2012 20:46

Вот способ импортировать файл с одного уровня выше, используя относительный путь.

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

#to import from one level above:
cwd = os.getcwd()
os.chdir("..")
below_path =  os.getcwd()
sys.path.append(below_path)
os.chdir(cwd)

Я не понимаю здесь логики. это слишком сложно

transilvlad 27.10.2012 01:13

Быстрый и грязный способ для пользователей Linux

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

ln -s (path)/module_name.py

или же

ln -s (path)/package_name

Примечание. «Модуль» - это любой файл с расширением .py, а «пакет» - это любая папка, содержащая файл __init__.py (который может быть пустым). С точки зрения использования модули и пакеты идентичны - оба предоставляют содержащиеся в них «определения и операторы» по запросу с помощью команды import.

См .: http://docs.python.org/2/tutorial/modules.html

Самый простой способ без каких-либо изменений в вашем скрипте - установить переменную среды PYTHONPATH. Поскольку sys.path инициализируется из этих мест:

  1. Каталог, содержащий входной скрипт (или текущий каталог).
  2. PYTHONPATH (список имен каталогов с одинаковыми синтаксис как переменная оболочки PATH).
  3. Значение по умолчанию, зависящее от установки.

Просто беги:

export PYTHONPATH=/absolute/path/to/your/module

Ваш sys.path будет содержать указанный выше путь, как показано ниже:

print sys.path

['', '/absolute/path/to/your/module', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']

Пример относительного sys.path:

# /lib/my_module.py
# /src/test.py


if __name__ == '__main__' and __package__ is None:
    sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib')))
import my_module

На основании ответа это.

В этом случае, чтобы импортировать Bar.py в Foo.py, сначала я бы превратил эти папки в пакеты Python следующим образом:

dirFoo\
    __init__.py
    Foo.py
    dirBar\
        __init__.py
        Bar.py

Тогда я бы сделал это в Foo.py так:

from .dirBar import Bar

Если бы я хотел, чтобы пространство имен выглядело как Bar.что бы ни или

from . import dirBar

Если бы я хотел использовать пространство имен dirBar.Bar.что бы ни. Этот второй случай полезен, если у вас есть больше модулей в пакете dirBar.

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

Решение:

У меня есть сценарий в D:/Books/MyBooks.py и некоторые модули (например, oldies.py). Мне нужно импортировать из подкаталога D:/Books/includes:

import sys,site
site.addsitedir(sys.path[0] + '\\includes')
print (sys.path)  # Just verify it is there
import oldies

Поместите print('done') в oldies.py, чтобы убедиться, что все в порядке. Этот способ всегда работает, потому что согласно определению Python, sys.path, инициализируемый при запуске программы, первый элемент этого списка, path[0], является каталогом, содержащим сценарий, который использовался для вызова интерпретатора Python.

Если каталог сценария недоступен (например, если интерпретатор вызывается в интерактивном режиме или если сценарий читается со стандартного ввода), path[0] - это пустая строка, которая направляет Python на поиск модулей в текущем каталоге в первую очередь. Обратите внимание, что каталог сценария вставлен перед записями, вставленными в результате PYTHONPATH.

В моей первой простой программе на Python break_time.py: https://github.com/ltfschoen/PythonTest мне пришлось использовать одну косую черту вместо двух (например, site.addsitedir(sys.path[0]+'/includes')). Использую систему: MacOS v10.11.5, Python 2.7.12, IDLE IDE 2.7.12, Tk 8.5.9

Luke Schoen 30.10.2016 10:05

Другое решение - установить пакет Py-require, а затем использовать следующее в Foo.py

import require
Bar = require('./dirBar/Bar')

На самом деле URL-адрес выглядит как pypi.org/project/require.py, и обратите внимание, что его необходимо установить через Pip.

Flash Sheridan 10.11.2018 00:39

@FlashSheridan Нет, это другой проект. Я удалил py-require, так как был уверен, что его никто не использует, хотя я не думал об этом посте. Если вам все еще нужна функция require(), вы можете взглянуть на мой проект Node.py: github.com/nodepy/nodepy

Niklas R 12.11.2018 23:48

Я не разбираюсь в питоне, поэтому, если в моих словах что-то не так, просто скажите мне. Если ваша файловая иерархия устроена следующим образом:

project\
    module_1.py 
    module_2.py

module_1.py определяет функцию под названием func_1(), module_2.py:

from module_1 import func_1

def func_2():
    func_1()

if __name__ == '__main__':
    func_2()

и вы запускаете python module_2.py в cmd, он выполнит то, что определяет func_1(). Обычно мы импортируем те же файлы иерархии. Но когда вы напишете from .module_1 import func_1 в module_2.py, интерпретатор Python скажет No module named '__main__.module_1'; '__main__' is not a package. Итак, чтобы исправить это, мы просто сохраняем только что внесенные изменения, перемещаем оба модуля в пакет и делаем третий модуль в качестве вызывающего для запуска module_2.py.

project\
    package_1\
        module_1.py
        module_2.py
    main.py

main.py:

from package_1.module_2 import func_2

def func_3():
    func_2()

if __name__ == '__main__':
    func_3()

Но причина, по которой мы добавляем . перед module_1 в module_2.py, заключается в том, что если мы этого не сделаем и запустим main.py, интерпретатор Python скажет No module named 'module_1', это немного сложно, module_1.py находится рядом с module_2.py. Теперь я позволяю func_1() в module_1.py что-то делать:

def func_1():
    print(__name__)

что __name__ записывает, кто вызывает func_1. Теперь мы сохраняем . перед module_1, запускаем main.py, он будет печатать package_1.module_1, а не module_1. Это указывает на то, что тот, кто называет func_1(), находится в той же иерархии, что и main.py, . подразумевает, что module_1 находится в той же иерархии, что и сам module_2.py. Таким образом, если точки нет, main.py распознает module_1 в той же иерархии, что и он сам, он может распознавать package_1, но не то, что находится «под» ним.

Теперь давайте немного усложним. У вас есть config.ini, и модуль определяет функцию для его чтения в той же иерархии, что и main.py.

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
    main.py

И по какой-то неизбежной причине вы должны вызвать его с помощью module_2.py, поэтому он должен импортировать из более высокой иерархии.

 import ..config
 pass

Две точки означают импорт из более высокой иерархии (три точки относятся к более высокому уровню и т. д.). Теперь запускаем main.py, интерпретатор скажет: ValueError:attempted relative import beyond top-level package. "Пакет верхнего уровня" здесь - main.py. Просто потому, что config.py находится рядом с main.py, они находятся в одной иерархии, config.py не находится «под» main.py, или он не «возглавляется» main.py, поэтому он находится за пределами main.py. Чтобы исправить это, самый простой способ:

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
main.py

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

Просто вы можете использовать: from Desktop.filename import something

Пример:

given that the file is name test.py in directory Users/user/Desktop , and will import everthing.

код:

from Desktop.test import *

Но убедитесь, что вы создали в этом каталоге пустой файл с именем "__init__.py".

не рекомендуется импортировать помеченные звездочкой. см .: stackoverflow.com/questions/2386714/why-is-import-bad

axolotl 18.06.2018 20:54

Я знаю, что именно поэтому я сначала написал import something, а затем сказал, чтобы упростить *, в основном, он не подходит для оперативной памяти, а также, если две функции имеют одно и то же имя, он накапливает ваш код

0x1996 07.07.2018 13:24

Это тоже работает, и это намного проще, чем что-либо с модулем sys:

with open("C:/yourpath/foobar.py") as f:
    eval(f.read())

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

Matthew 26.09.2018 23:56

Другие вопросы по теме