"cannot import name '__main__" 尝试从我创建的 wheel 中 运行 控制台命令时
"cannot import name '__main__" when trying to run a console command from the wheel I created
几个月来,我一直在努力为我的项目 'rpn' (https://github.com/ConceptJunkie/rpn) 创建一个轮子。我终于到了一切似乎都正确的地步,除了我试图在 setup.py.
中创建的控制台命令
我的项目有多个模块,我的 setup.py,我将在下面 post 创建一个似乎可以正常工作的轮子。我没有对 virtualenv 进行过广泛的测试,因为我想掌握正确的基础知识。当我用 pip 安装轮子时,我可以 运行 python 并导入我的模块和 运行 功能就好了。但是,我将该项目(和一些辅助实用程序)用作命令行应用程序,所以我希望轮子为我创建一些命令。
我在 Windows,所以当我安装轮子时,它会为我定义的每个命令创建一个小的 EXE 文件,但是当我尝试 运行 这些命令时,我得到这个输出:
c:\app\python36\scripts>makeRPNUnits.exe
Traceback (most recent call last):
File "c:\app\python36\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "c:\app\python36\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\app\python36\Scripts\makeUnits.exe\__main__.py", line 5, in <module>
ImportError: cannot import name '__main__'
这是我 运行 准备应用程序使用的数据文件所需的小实用程序之一,但其他命令都做同样的事情。如果我进入 Python 我可以 运行 就好了:
c:\app\python36\scripts>python
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import makeUnits
>>> makeUnits.main( )
makeUnits 6.999.13 (7.0b13) - RPN command-line calculator unit conversion data generator
copyright (c) 2018 (1988), Rick Gutleber (rickg@his.com)
[and so on...]
实际应用我也可以通过Python:
>>> rpn.handleOutput( rpn.rpn( [ '2', '2', '+' ] ) )
4
我花了几个小时寻求帮助...设置工具的文档非常稀疏和不透明,我只能在其他地方找到很小的信息片段,而且经常相互矛盾。了解细节永远不够,但足以做出有根据的猜测。
我的目录结构如下所示:
rpn/
├── rpndata
│ ├── various_text_files
└── setup.py
__init__.py
rpn.py
makeUnits.py
makeHelp.py
MANIFEST.in
rpn*.py
我希望创建的每个命令都在处理 main 的单独模块中表示。例如:
if __name__ == '__main__':
main( )
其余文件实现了程序和各种实用程序使用的所有功能。同样,大部分内容都在 Python 中运行,但 /python36/scripts 中的命令失败并出现上述错误。
整个setup.py比较冗长,但相关的部分是这样的:
entry_points = {
'console_scripts': [
'rpn = rpn.rpn:__main__',
'makeRPNHelp = rpn.makeHelp:__main__',
'makeRPNUnits = rpn.makeUnits:__main__',
'prepareRPNPrimeData = rpn.preparePrimeData:__main__',
'testRPN = rpn.testRPN:__main__',
],
}
专家们可能需要更多细节,我很乐意提供,当然,整个项目都可以从 GitHub 获得。该项目相当大,而且有些复杂...它超出了我管理 Python 项目的能力,因为这对我来说只是一种爱好,我在日常工作中使用 C++。
感谢您的帮助。
对于您项目的特殊情况,您已经在每个模块中定义了一个 main
函数,因此要使 setuptool 入口点起作用,您可以直接直接引用它们,就好像您如何导入它们一样 (import makeUnits
), 即:
entry_points = {
'console_scripts': [
'rpn = rpn:main',
'makeRPNHelp = makeHelp:main',
'makeRPNUnits = makeUnits:main',
...
]
}
为什么您可能对需要 __main__
感到困惑是因为这个值被分配给模块 __name__
如果那是可执行脚本,或者将模块命名为 __main__.py
is a way to allow a module to be executed directly using python -m example.module
on the command line (pip
for instance does this python -m pip
工作)。但是,对于标准入口点,只需直接引用 module:attr
,它就会达到您的预期。
此外,请考虑通过 documentation about packaging on the Python site, as it will address how to properly package a project (which setuptools documentation don't actually teach, as you noted). Also consider creating a directory called rpn
and putting your rpn*.py files into there to better organize your program code into its own namespace (so to make the entry point as you originally defined it (e.g. makeHelp = rpn.makeHelp:main
work; naturally this comes with a change in how the main function is imported (from rpn.makeHelp import main
)), though I note that on PyPI (the official python package index) that there is already a rpn
package。
几个月来,我一直在努力为我的项目 'rpn' (https://github.com/ConceptJunkie/rpn) 创建一个轮子。我终于到了一切似乎都正确的地步,除了我试图在 setup.py.
中创建的控制台命令我的项目有多个模块,我的 setup.py,我将在下面 post 创建一个似乎可以正常工作的轮子。我没有对 virtualenv 进行过广泛的测试,因为我想掌握正确的基础知识。当我用 pip 安装轮子时,我可以 运行 python 并导入我的模块和 运行 功能就好了。但是,我将该项目(和一些辅助实用程序)用作命令行应用程序,所以我希望轮子为我创建一些命令。
我在 Windows,所以当我安装轮子时,它会为我定义的每个命令创建一个小的 EXE 文件,但是当我尝试 运行 这些命令时,我得到这个输出:
c:\app\python36\scripts>makeRPNUnits.exe
Traceback (most recent call last):
File "c:\app\python36\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "c:\app\python36\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\app\python36\Scripts\makeUnits.exe\__main__.py", line 5, in <module>
ImportError: cannot import name '__main__'
这是我 运行 准备应用程序使用的数据文件所需的小实用程序之一,但其他命令都做同样的事情。如果我进入 Python 我可以 运行 就好了:
c:\app\python36\scripts>python
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import makeUnits
>>> makeUnits.main( )
makeUnits 6.999.13 (7.0b13) - RPN command-line calculator unit conversion data generator
copyright (c) 2018 (1988), Rick Gutleber (rickg@his.com)
[and so on...]
实际应用我也可以通过Python:
>>> rpn.handleOutput( rpn.rpn( [ '2', '2', '+' ] ) )
4
我花了几个小时寻求帮助...设置工具的文档非常稀疏和不透明,我只能在其他地方找到很小的信息片段,而且经常相互矛盾。了解细节永远不够,但足以做出有根据的猜测。
我的目录结构如下所示:
rpn/
├── rpndata
│ ├── various_text_files
└── setup.py
__init__.py
rpn.py
makeUnits.py
makeHelp.py
MANIFEST.in
rpn*.py
我希望创建的每个命令都在处理 main 的单独模块中表示。例如:
if __name__ == '__main__':
main( )
其余文件实现了程序和各种实用程序使用的所有功能。同样,大部分内容都在 Python 中运行,但 /python36/scripts 中的命令失败并出现上述错误。
整个setup.py比较冗长,但相关的部分是这样的:
entry_points = {
'console_scripts': [
'rpn = rpn.rpn:__main__',
'makeRPNHelp = rpn.makeHelp:__main__',
'makeRPNUnits = rpn.makeUnits:__main__',
'prepareRPNPrimeData = rpn.preparePrimeData:__main__',
'testRPN = rpn.testRPN:__main__',
],
}
专家们可能需要更多细节,我很乐意提供,当然,整个项目都可以从 GitHub 获得。该项目相当大,而且有些复杂...它超出了我管理 Python 项目的能力,因为这对我来说只是一种爱好,我在日常工作中使用 C++。
感谢您的帮助。
对于您项目的特殊情况,您已经在每个模块中定义了一个 main
函数,因此要使 setuptool 入口点起作用,您可以直接直接引用它们,就好像您如何导入它们一样 (import makeUnits
), 即:
entry_points = {
'console_scripts': [
'rpn = rpn:main',
'makeRPNHelp = makeHelp:main',
'makeRPNUnits = makeUnits:main',
...
]
}
为什么您可能对需要 __main__
感到困惑是因为这个值被分配给模块 __name__
如果那是可执行脚本,或者将模块命名为 __main__.py
is a way to allow a module to be executed directly using python -m example.module
on the command line (pip
for instance does this python -m pip
工作)。但是,对于标准入口点,只需直接引用 module:attr
,它就会达到您的预期。
此外,请考虑通过 documentation about packaging on the Python site, as it will address how to properly package a project (which setuptools documentation don't actually teach, as you noted). Also consider creating a directory called rpn
and putting your rpn*.py files into there to better organize your program code into its own namespace (so to make the entry point as you originally defined it (e.g. makeHelp = rpn.makeHelp:main
work; naturally this comes with a change in how the main function is imported (from rpn.makeHelp import main
)), though I note that on PyPI (the official python package index) that there is already a rpn
package。