编译.pyw文件使其像.pyc文件一样无控制台运行

4 投票
4 回答
13687 浏览
提问于 2025-04-15 15:45

我想把一个.pyw文件编译成.pyc文件,但不想让它在控制台中运行。当我直接编译这个文件时,结果是一个.pywc文件,但看起来pythonw.exe并没有把这个扩展名当作它的文件类型,就像python.exe对待.pyc文件那样。

结果就是,当你尝试直接双击这个文件时,它没有任何反应,或者如果你把扩展名改成.pyc,就会出现控制台窗口。

有没有人知道怎么解决这个问题?有没有办法让.pyc文件在没有控制台的情况下运行?

谢谢!

更新:
因为通过execfile运行或者在Windows中双击图标并不能生成这个文件的编译版本,所以我在命令行中启动Python,然后:

import py_compile
py_compile.compile("[FileName].pyw")

这就是我得到.pywc扩展名的原因。我的Python版本是2.5.4。

4 个回答

3

你可以使用FTYPE和ASSOC这两个命令,把.pywc文件和pythonw.exe程序关联起来。

ASSOC命令是用来把文件扩展名和文件类型连接起来的,而FTYPE命令则是把文件类型和打开它所用的命令连接起来。下面的命令展示了我电脑上已有的关联情况:

C:\Python26>assoc .py
.py=Python.File

C:\Python26>assoc .pyc
.pyc=Python.CompiledFile

C:\Python26>assoc .pyw
.pyw=Python.NoConFile

C:\Python26>assoc .pywc
File association not found for extension .pywc

这些命令显示了每个扩展名是和哪个程序通过文件类型关联的:

C:\Python26>ftype Python.CompiledFile
Python.CompiledFile="C:\Python26\python.exe" "%1" %*

C:\Python26>ftype Python.NoConFile
Python.NoConFile="C:\Python26\pythonw.exe" "%1" %*

所以看起来你可以这样把.pywc文件关联到Python.NoConFile:

assoc .pywc=Python.NoConFile
4

读取 .pyw 文件的解释器也可以读取编译过的 .pyc 格式的文件。你只需要把 .pyc 文件的名字改成 .pyw 就可以了。这样它就能运行了(不过还是要注意版本的问题),而且你不会看到那个难看的控制台窗口。

7

(接着OP帖子中的一些讨论)

如果你需要给客户或用户提供编译好的应用程序,格式是*.pyc或*.pyo,并且希望在执行时不打开控制台,一个不错的选择是留一个*.pyw的包装文件来调用主应用程序。

假设主应用程序在main.pyc中,入口点是main,我们把包装文件叫做top.pyw,它通常看起来像这样:

# top.pyw file
import main
if __name__ == "__main__":
    import sys
    main.main(*sys.argv[1:])

你的main.py文件看起来会是这样的:

# main.py file
"""
Main module documentation (optional)
"""
# import modules

# function and class definitions

def main(*argv):
    # Parses the options (optional)
    import optparse
    parser = optparse.OptionParser(usage="%prog [<options>]\n" + __doc__)
    parser.add_option(...)
    parser.add_option(...)
    opt, args = parser.parse_args(list(argv))
    # Calls the appropriate function:
    my_function(...)

另外要注意,*.pyc文件通常是特定版本的。你可以检查一下上面的解决方案是否与pyInstaller和类似的“独立”分发方法兼容。

编辑 => 事实上,如果你使用pyInstaller,你可以简单地把所有脚本包含进去,生成一个独立于Python安装的可执行文件,并且启动时不会有控制台(在创建规格时使用-w选项)。你甚至不需要使用包装文件或更改扩展名。虽然文件会大一些,但这可能正是你想要的。

最后,万一你想要的是这个:如果你不希望别人从编译后的字节码中提取源代码,别忘了你需要额外的保护措施。这被称为代码混淆,在SO上还有其他相关的讨论(比如这个)。如果你在这个问题上只找到旧的答案,不要犹豫,发个新问题,因为这些事情变化得很快。

撰写回答