Создание колеса Python: нет модуля с именем ______

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

Вот моя примерная структура:

wheel_test
|-setup.py
|-toto
  |-__init__.py
  |-main.py
  |-tata.py
  |-subfolder
    |-__init__.py
    |-titi.py

main.py

# coding: utf8
from tata import tata
import subfolder.titi as titi

def test_fct():
  t1 = tata()
  print(f't1 number = {t1.random_number}')
  print(f'Is t1 number even: {titi.is_even(t1.random_number)}')

test_fct()

(Здесь t1 — это экземпляр класса tata, который просто хранит случайное число в self.random_number, а файл titi.py просто содержит функцию is_even(number), сообщающую, является ли число четным или нет)

Это отлично работает при запуске:

>  python "some_path\wheel_test\toto\main.py"
t1 number = 11
Is t1 number even: False

Но затем я хочу сделать из этого колесо, используя установочный файл: setup.py

# coding: utf8
import os
from setuptools import find_packages, setup

root = os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))
os.chdir(root)

setup(
  name='toto',
  packages=find_packages(),
  version='0.1',
  description='Wheel test',
  author='Arkeen',
  license='None',
)

(Я скопировал os.chdir строк из [этот пост])

Это создаст файл toto-0.1-py3-none-any.whl. Затем я запускаю $ pip install path_to_newly_created_whell/toto-0.1-py3-none-any.whl, что кажется нормальным.

Но когда я хочу запустить этот код:

# coding: utf8
import toto.main as maintoto
maintoto.test_fct()

Я получил следующую ошибку:

File "some_path\wheel_test\toto\main.py", line 2, in <module>
  from tata import tata
ModuleNotFoundError: No module named 'tata'

Так почему такой исход? Почему этот код отлично работает с Python, но не с колесом?


Правка: спасибо @Countour-Integral за то, что указали мне правильное направление. Тем не менее, мне пришлось углубиться в Python modules, packages, относительный и абсолютный import, чтобы полностью понять это. Итак, всем, кто столкнулся с подобной проблемой, рекомендую прочитать это:


person Arkeen    schedule 30.11.2020    source источник


Ответы (1)


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

В следующем фрагменте вы запускаете main.py как python path/to/main.py

import subfolder.titi as titi # Does not throw any error

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

Вместо этого, когда вы пытаетесь запустить setup.py для сборки, интерпретатор запустит все как пакет и, таким образом, не будет искать ни в каких локальных каталогах. Вам придется изменить свой импорт следующим образом

# notice the .
from .subfolder import titi 
from .tata import tata 

Ваша файловая структура выглядит примерно так

-> module (directory)
---- main.py
---- tata.py
----> subfolder (directory)
-------- titi.py

чтобы запустить любой из них как модуль, вместо использования python main.py вам придется вернуться на 1 шаг назад, в родительский каталог module и использовать python -m module main.py,и убедиться, что вы используете импорт с . для ссылки на файлы в том же каталоге. Обычно так делается разработка пакетов python-pip, чтобы упростить процесс setup.py.

person Countour-Integral    schedule 30.11.2020
comment
Спасибо, наконец-то понял :) - person Arkeen; 10.12.2020