我正在尝试为我已经编写的脚本创建可执行文件。它将由机器上没有 python 的同事使用,因此我想创建一个可执行文件以使他们的生活更轻松。我目前只是想让 py2exe 工作并为一个简单的脚本创建一个可执行文件,该脚本简单地打印 hello world 和数学模块中的常量 e(只是为了了解 py2exe 的工作原理)。
我的设置脚本如下:
from distutils.core import setup
import py2exe
import math
setup(
console=[{'script':'hello.py'}],
options={
'py2exe':{
'packages' : ['math'],
'bundle_files':1
},
},
version='1.0.0'
)
其中 hello.py 只是:
import math
print('hello world!')
print(f'Here is e: {math.exp(1)}')
在 cmd 中调用“python setup.py py2exe”后,错误来自此堆栈
Traceback (most recent call last):
File ".\setup.py", line 5, in <module>
setup(
File ".\Anaconda3\lib\site-packages\setuptools\_distutils\core.py", line 148, in setup
return run_commands(dist)
File ".\Anaconda3\lib\site-packages\setuptools\_distutils\core.py", line 163, in run_commands
dist.run_commands()
File ".\Anaconda3\lib\site-packages\setuptools\_distutils\dist.py", line 967, in run_commands
self.run_command(cmd)
File ".\Anaconda3\lib\site-packages\setuptools\dist.py", line 1214, in run_command
super().run_command(command)
File ".\Anaconda3\lib\site-packages\setuptools\_distutils\dist.py", line 986, in run_command
cmd_obj.run()
File ".\Anaconda3\lib\site-packages\py2exe\distutils_buildexe.py", line 192, in run
self._run()
File ".\Anaconda3\lib\site-packages\py2exe\distutils_buildexe.py", line 273, in _run
builder.build()
File ".\Anaconda3\lib\site-packages\py2exe\runtime.py", line 250, in build
self.build_archive(exe_path)
File ".\Anaconda3\lib\site-packages\py2exe\runtime.py", line 490, in build_archive
base = dist_path.rsplit('\\', 1)[0]
AttributeError: 'NoneType' object has no attribute 'rsplit'
要将 .py 文件转换为 .exe,您需要安装 auto-py-to-exe
Windows
pip install auto-py-to-exe
安装完成后,打开cmd然后输入
auto-py-to-exe
然后指定脚本的路径以及要保存.exe文件的位置。
快速而肮脏的修复 - 我修改了runtime.py(在异常源中列出)并添加了一个检查以在dist_path为None时继续。它可以编译控制台应用程序,但这可能会给其他人带来意想不到的后果。
if mod.__path__ is not None and mod.__name__[0] != '_': # attempt to select valid packages
try:
dist = pkg_resources.get_distribution(mod.__name__)
dist_path = dist._provider.egg_info
# Added if statement
if dist_path == None:
continue
base = dist_path.rsplit('\\', 1)[0]
name = dist_path.split(base + '\\')[1]