Skip to main content
 首页 » 编程设计

python之扩展已编译 Python 脚本的功能

2025年05月04日32sky-heaven

我不是程序员,所以我什至不知道我应该用什么术语来问这个问题。假设我已经将一个 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)