建造一个 python 轮子:"no module named ______"
Building a python wheel : "no module named ______"
我正在尝试在一个复杂的程序上构建一个 python 轮子,但我遇到了导入问题。所以我设法在一个基本示例上重现了它。该程序在直接调用时运行良好,但在尝试从已安装的 wheel 中导入时无法运行。
这是我的示例结构:
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
是classtata
的一个实例,只是在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
才能完全理解这一点。所以,对于这里有类似问题的任何人,我建议阅读这篇文章:
您得到 ModuleNotFoundError
,因为解释器正在搜索名为 tata
的全局模块,而不是在当前目录中查找。您还在您的第一个代码块中重复此行为。
在以下代码段中,您 运行宁 main.py
为 python path/to/main.py
import subfolder.titi as titi # Does not throw any error
这不会抛出任何错误的原因是,你 不是 运行ning 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
你必须向后退一步,进入 module
的父目录并使用 python -m module main.py
,并确保您使用的是 .引用同一目录中的文件。通常这是 python-pip 包的开发方式,以便在 setup.py
过程中更容易。
我正在尝试在一个复杂的程序上构建一个 python 轮子,但我遇到了导入问题。所以我设法在一个基本示例上重现了它。该程序在直接调用时运行良好,但在尝试从已安装的 wheel 中导入时无法运行。
这是我的示例结构:
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
是classtata
的一个实例,只是在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
才能完全理解这一点。所以,对于这里有类似问题的任何人,我建议阅读这篇文章:
您得到 ModuleNotFoundError
,因为解释器正在搜索名为 tata
的全局模块,而不是在当前目录中查找。您还在您的第一个代码块中重复此行为。
在以下代码段中,您 运行宁 main.py
为 python path/to/main.py
import subfolder.titi as titi # Does not throw any error
这不会抛出任何错误的原因是,你 不是 运行ning 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
你必须向后退一步,进入 module
的父目录并使用 python -m module main.py
,并确保您使用的是 .引用同一目录中的文件。通常这是 python-pip 包的开发方式,以便在 setup.py
过程中更容易。