如何强制 setup.py 包含 `__init__.py` 文件并使我的包可导入?
How do I force setup.py to include the `__init__.py` file and make my package importable?
我正在尝试让使用 pip
安装它的人可以导入我的 Python project。虽然它包含一个 __init__.py
并且在本地作为一个包工作,但我似乎误解了 setuptools 的工作原理。
我运行下面三个命令上传包。
python3 setup.py sdist bdist_wheel
python3 -m pip install --upgrade twine
python3 -m twine upload dist/*
然后在另一台机器上,我运行 pip3 install smux.py
。结果是我可以作为命令访问 smux.py
,但是在尝试导入它时出现导入错误。
python3
Python 3.8.5 (default, Jul 28 2020, 12:59:40)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import smux
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'smux'
在 运行 执行上面的 setup.py
命令后,我检查了当前目录中的 smux.py.egg-info/SOURCES.txt
并发现它包含以下内容:
README.md
setup.py
smux.py
smux.py.egg-info/PKG-INFO
smux.py.egg-info/SOURCES.txt
smux.py.egg-info/dependency_links.txt
smux.py.egg-info/top_level.txt
文件 __init__.py
丢失。
如何将该文件放入包中,或修改设置调用以使 smux
可导入?
您的 setup
调用如下所示:
setup(
name="smux.py",
version='0.1.1',
scripts=['smux.py'],
author="Henry Qin",
author_email="root@hq6.me",
description="Simple tmux launcher that will take less than 2 minutes to learn and should work across all versions of tmux",
long_description=long_description,
platforms=["All platforms that tmux runs on."],
license="MIT",
url="https://github.com/hq6/smux"
)
使用 scripts
参数,您已经告诉 setuptools smux.py
是一个脚本,而不是一个模块。因此,它作为脚本而不是模块安装。
您的代码不需要 __init__.py
,也不应该有。拥有 __init__.py
将无济于事。您需要告诉 setuptools 将您的文件安装为模块而不是脚本,并单独注册一个入口点,在 entry_points
参数中使用 console_scripts
条目:
setup(
...
# no scripts= line
py_modules=['smux'],
entry_points={
'console_scripts': ['smux=smux:main']
}
)
然后当您的代码被安装时,smux
将是可导入的,并且将有一个 smux
脚本可从命令行调用 smux.main
.
另一个答案是更符合犹太洁食和现代的答案,如果我没有根据名称 smux.py
遗留的脚本,我会使用它并将脚本命名为 smux
。不幸的是,其他人已经包装 smux.py
并且破坏他们的脚本是不友好的。
这是我为避免循环依赖问题所做的工作,该问题是由于遗留脚本名称以 .py
结尾并与模块命名冲突而引起的。
我最终修改了 setup
调用,使其具有以下两项。
py_modules=['smux'],
scripts=['smux.py']
我的实验表明,这具有使模块可导入的预期效果,同时保留名称为 smux.py
的工作脚本。
我正在尝试让使用 pip
安装它的人可以导入我的 Python project。虽然它包含一个 __init__.py
并且在本地作为一个包工作,但我似乎误解了 setuptools 的工作原理。
我运行下面三个命令上传包。
python3 setup.py sdist bdist_wheel
python3 -m pip install --upgrade twine
python3 -m twine upload dist/*
然后在另一台机器上,我运行 pip3 install smux.py
。结果是我可以作为命令访问 smux.py
,但是在尝试导入它时出现导入错误。
python3
Python 3.8.5 (default, Jul 28 2020, 12:59:40)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import smux
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'smux'
在 运行 执行上面的 setup.py
命令后,我检查了当前目录中的 smux.py.egg-info/SOURCES.txt
并发现它包含以下内容:
README.md
setup.py
smux.py
smux.py.egg-info/PKG-INFO
smux.py.egg-info/SOURCES.txt
smux.py.egg-info/dependency_links.txt
smux.py.egg-info/top_level.txt
文件 __init__.py
丢失。
如何将该文件放入包中,或修改设置调用以使 smux
可导入?
您的 setup
调用如下所示:
setup(
name="smux.py",
version='0.1.1',
scripts=['smux.py'],
author="Henry Qin",
author_email="root@hq6.me",
description="Simple tmux launcher that will take less than 2 minutes to learn and should work across all versions of tmux",
long_description=long_description,
platforms=["All platforms that tmux runs on."],
license="MIT",
url="https://github.com/hq6/smux"
)
使用 scripts
参数,您已经告诉 setuptools smux.py
是一个脚本,而不是一个模块。因此,它作为脚本而不是模块安装。
您的代码不需要 __init__.py
,也不应该有。拥有 __init__.py
将无济于事。您需要告诉 setuptools 将您的文件安装为模块而不是脚本,并单独注册一个入口点,在 entry_points
参数中使用 console_scripts
条目:
setup(
...
# no scripts= line
py_modules=['smux'],
entry_points={
'console_scripts': ['smux=smux:main']
}
)
然后当您的代码被安装时,smux
将是可导入的,并且将有一个 smux
脚本可从命令行调用 smux.main
.
另一个答案是更符合犹太洁食和现代的答案,如果我没有根据名称 smux.py
遗留的脚本,我会使用它并将脚本命名为 smux
。不幸的是,其他人已经包装 smux.py
并且破坏他们的脚本是不友好的。
这是我为避免循环依赖问题所做的工作,该问题是由于遗留脚本名称以 .py
结尾并与模块命名冲突而引起的。
我最终修改了 setup
调用,使其具有以下两项。
py_modules=['smux'],
scripts=['smux.py']
我的实验表明,这具有使模块可导入的预期效果,同时保留名称为 smux.py
的工作脚本。