我不是程序员,所以我什至不知道我应该用什么术语来问这个问题。假设我已经将一个 Python 脚本编译为一个 .exe(我使用 py2exe 来执行此操作)。这是主要程序。现在,我想给它添加一些额外的功能,但我不想用添加的功能重新编译整个脚本。我试着在网上搜索一些东西,我找到了用 Python 脚本(比如某种插件)扩展 C++ 或其他应用程序的示例。但是我不知道如何使用已经用 Python 编写的应用程序来完成它。
我试过这个:我编写了 major.py(这是我构建可执行文件的脚本)和 stuff.py。在 major 我这样写:
def generic():
import stuff
while True:
param=input('what did you say? ')
stuff.speak(param)
generic()
在 stuff 中我这样写:
def speak(param):
print(param)
然后我用py2exe创建了一个.exe。它按预期工作,当我在命令行中运行程序时说“你说什么?”等到我输入一些东西,然后它打印我输入的内容。 然后,我将 stuff.py 更改为:
def speak(param):
print('I said '+param)
希望现在在执行之前创建的 .exe 时,它会打印“我说……”加上我输入的任何内容。显然,它不起作用,程序继续像以前一样运行。所以我猜测一旦我导入了 stuff 并创建了 .exe 文件,该导入是永久性的,不允许我更改 stuff 中的任何内容。我该怎么办?
请您参考如下方法:
py2exe 将编译后的脚本打包到可执行文件中。
您需要重新创建可执行文件(它将重新编译任何更改的脚本)以查看更改是否生效。
编辑以下评论: 如果从可执行文件内部动态导入/重新导入模块,就可以做到这一点。
在你的主脚本中你这样做(见下面的代码)
mod, error = loadmodule('mystuff.py')
if mod is not None:
# loading succeeded you can now proceed and do things with it
pass
当然,您必须在 py2exe 打包到可执行文件中的脚本中保留 mystuff.py。在上面的示例中,mystuff.py 将与可执行文件位于同一目录中。
加载代码:
def loadmodule(modpath, modname=''):
if not modpath.endswith('.py'):
modpath += '.py'
# generate a random name for the module
if not modname:
modpathbase = os.path.basename(modpath)
modname, _ = os.path.splitext(modpathbase)
version = (sys.version_info[0], sys.version_info[1])
if version < (3, 3):
mod, e = loadmodule2(modpath, modname)
else:
mod, e = loadmodule3(modpath, modname)
return mod, e
def loadmodule2(modpath, modname):
import imp
try:
mod = imp.load_source(modname, modpath)
except Exception as e:
return (None, e)
return (mod, None)
def loadmodule3(modpath, modname):
import importlib.machinery
try:
loader = importlib.machinery.SourceFileLoader(modname, modpath)
mod = loader.load_module()
except Exception as e:
return (None, e)
return (mod, None)
