Python:如何在关闭父应用后(不)保持COM对象在内存中持久?

1 投票
1 回答
1463 浏览
提问于 2025-04-18 01:44

我正在开发一个(相当大的)Python/Tkinter应用程序(在Windows 7下使用Python 2.7),这个应用程序有很多功能,其中之一是通过COM接口调用Matlab。Matlab和COM部分的基本结构如下:

import Tkinter
import pythoncom
import win32com.client

class App( object ):

    def __init__( self, parent ):
        Tkinter.Button( root, text="Start Matlab", command=self.start_matlab ).grid()

    def start_matlab( self ):
        self.matlab = win32com.client.Dispatch( "Matlab.Application" )

root = Tkinter.Tk()
App( root )
root.mainloop()

我在这个简化的代码中观察到的行为是:运行应用程序并点击按钮会创建一个Matlab实例(打开一个Matlab命令窗口),当关闭Tkinter应用程序时,这个Matlab窗口和任务管理器中的相应条目也会消失。重复这个过程时,Matlab会重新启动。

但是,当我在我的“真实”应用程序中做“同样的事情”时,关闭应用程序后,Matlab实例仍然存在。此外,当我重新启动应用程序并运行那个“启动”Matlab的部分时,它只是重新使用了在第一次会话结束后仍然留在内存中的Matlab实例。不幸的是,我无法找到一个合理小的代码示例来展示这种行为。

有没有人知道这可能是什么原因呢?

如何控制当创建它的父Python应用程序关闭时,COM对象是被销毁还是仍然保留在内存中?

1 个回答

1

下面是如何使用Tkinter的协议处理器来明确地移除COM对象的方法:

import Tkinter
import pythoncom
import win32com.client

class App( object ):

    def __init__( self, parent ):
        self.parent = parent #reference to root
        Tkinter.Button( root, text="Start Matlab", command=self.start_matlab ).grid()
        self.parent.protocol('WM_DELETE_WINDOW', self.closeAll) #protocol method

    def start_matlab( self ):
        self.matlab = win32com.client.Dispatch( "Matlab.Application" )

    def closeAll(self):
        del self.matlab       #delete the COM object
        self.parent.destroy() #close the window

root = Tkinter.Tk()
App( root )
root.mainloop()

参考资料:从内存中移除COM对象

了解更多关于协议的信息

撰写回答