Не могу импортировать собственные модули в Python


144

Мне сложно понять, как импорт модулей работает в Python (я никогда раньше не делал этого на любом другом языке).

Допустим, у меня есть:

myapp/__init__.py
myapp/myapp/myapp.py
myapp/myapp/SomeObject.py
myapp/tests/TestCase.py

Сейчас пытаюсь получить что-то вроде этого:

myapp.py
===================
from myapp import SomeObject
# stuff ...

TestCase.py
===================
from myapp import SomeObject
# some tests on SomeObject

Однако я определенно делаю что-то не так, поскольку Python не видит, что myappэто модуль:

ImportError: No module named myapp

Ответы:


97

В вашем конкретном случае похоже, что вы пытаетесь импортировать SomeObjectиз скриптов myapp.py и TestCase.py. Из myapp.py сделайте

import SomeObject

поскольку он находится в той же папке. Для TestCase.py выполните

from ..myapp import SomeObject

Однако это будет работать, только если вы импортируете TestCase из пакета. Если вы хотите работать напрямую python TestCase.py, вам придется испортить свой путь. Это можно сделать в Python:

import sys
sys.path.append("..")
from myapp import SomeObject

хотя обычно это не рекомендуется.

В общем, если вы хотите, чтобы другие люди использовали ваш пакет Python, вам следует использовать distutils для создания сценария установки. Таким образом, любой может легко установить ваш пакет с помощью такой команды, python setup.py installи он будет доступен везде на его машине. Если вы серьезно относитесь к пакету, вы можете даже добавить его в индекс пакетов Python, PyPI .


Я попытался просто использовать importв моем, TestCase.pyно он все равно дал мне ту же ошибку. Я предполагаю, что это потому, что он находится в подкаталоге __init__.py?
n0pe

Ой, подождите, я думаю, я понял. Если мои тестовые случаи вызываются из пакета, я смогу использовать from ... import ...право?
n0pe

1
Вы сделаете это только в том случае, если TestCase импортируется извне пакета - например, если я запускаю from myapp.tests import TestCase from a script outside myapp. If you're running python TestCase.py` в папке тестов, вы не можете выполнять относительный импорт
Дэвид Робинсон

1
Я запустил «pip install -e.», Чтобы установить myapp, но при попытке запустить TestCase в коде Visual Studio я все еще получаю «ImportError: No module named myapp». но если я запускаю «python», а затем в python запускаю «из myapp import SomeObject», он работает. Что я делаю не так?
dagrun 09

@DavidRobinson Я использовал метод, который вы упомянули, который не показал ошибок после выполнения from fodername import file_name_of_my_py_code, но когда я попытался получить доступ к объекту, определенному в file_name_of_my_py_code.pyнем, говоритNameError: name 'ClassName' is not defined
Кавин Раджу S

45

Функция importищет файлы в вашем окружении PYTHONPATH. переменная и ваш локальный каталог. Таким образом, вы можете поместить все свои файлы в один каталог или экспортировать введенный путь в терминал:

export PYTHONPATH="$PYTHONPATH:/path_to_myapp/myapp/myapp/"

2
Тогда как я могу убедиться, что он работает для всех, кто будет им пользоваться? Я бы предпочел не указывать им, чтобы они установили определенные переменные среды перед запуском.
n0pe

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

4
Для пользователей Windows, вместо того, чтобы exportмы установили «PYTHONPATH =% PYTHONPATH%; C: \ path_to_myapp \ myapp \ myapp \»
popular.by.Jesus 02

В коде vs я смог исправить это, добавив переменную Env PYTHONPATH в мой launch.json: "env": {"PYTHONPATH": "$ {workspaceFolder}"}
Майкл Армитедж

11

путь экспорта - хороший способ. Другой способ - добавить .pth в местоположение ваших пакетов сайта. На моем Mac мой python хранит пакеты сайтов в / Library / Python, как показано ниже

/Library/Python/2.7/site-packages

Я создал файл с именем awesome.pth в /Library/Python/2.7/site-packages/awesome.pth и в этом файле поместил следующий путь, который ссылается на мои потрясающие модули

/opt/awesome/custom_python_modules

1
в случае, если я работаю в Windows, как мне это сделать?
Нвавель А Ируме

Я не уверен. В случае, если вы используете windows. Найдите какое-нибудь программное обеспечение vm и используйте linux. Или - см. Этот ответ об экспорте переменных в окнах. stackoverflow.com/questions/559816/…
jmontross 08

это именно то, что мне нужно
Lee88

1
Рад слышать, что @ Lee88 - мне потребовалось время, чтобы самому разобраться :)
jmontross

9

Можешь попробовать

from myapp.myapp import SomeObject

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


3

В вашем первом каталоге myapp вы можете добавить файл setup.py и добавить два кода Python в setup.py

from setuptools import setup
setup(name='myapp')

в вашем первом каталоге myapp в командной строке используйте pip install -e. установить пакет


2

pip installв Windows 10 по умолчанию устанавливается в 'Program Files / PythonXX / Lib / site-packages', который является каталогом, требующим прав администратора. Поэтому я исправил свою проблему, запустив pip install от имени администратора (вам нужно открыть командную строку от имени администратора, даже если вы вошли в систему с учетной записью администратора). Кроме того, безопаснее вызывать pip из python.
например,
python -m pip install <package-name>
вместо
pip install <package-name>


1

Тебе нужно иметь

__init__.py

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


0

В моем случае это было сюрпризом для Windows и Python, несмотря на то, что имена файлов Windows не чувствительны к регистру, импорт Python -. Поэтому, если у вас есть Stuff.pyфайл, вам нужно импортировать это имя как есть.


0

скажем, я пишу модуль

import os
my_home_dir=os.environ['HOME'] // in windows 'HOMEPATH'
file_abs_path=os.path.join(my_home_dir,"my_module.py")

with open(file_abs_path,"w") as f:
   f.write("print('I am loaded successfully')")

import importlib
importlib.util.find_spec('my_module') ==> cannot find

мы должны указать python, где искать модуль. мы должны добавить наш путь кsys.path

 import sys
 sys.path.append(file_abs_path)

теперь importlib.util.find_spec('my_module')возвращается:

  ModuleSpec(name='my_module', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7fa40143e8e0>, origin='/Users/name/my_module.py')

мы создали наш модуль, мы сообщили python его путь, теперь мы можем его импортировать

 import my_module

//I am loaded successfully
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.