pythonwin32comclosuresExcel进程

试图通过python改变Excel_sheet,完全混淆进程恢复。

import win32com.client class XlsClass: def __init__(self ,filename=None ,*,Visible=False ,Alerts=False): self.xlApp = win32com.client.Dispatch('Excel.Application') self.xlApp.Visible = Visible self.xlApp.DisplayAlerts = Alerts if filename: self.filename = filename self.xlBook = self.xlApp.Workbooks.Open(filename) else: self.xlBook = self.xlApp.Workbooks.Add() self.filename = '' def __del__(self): self.xlBook.Close() self.xlApp.Quit() 

有时代码运行良好,但是有时python会像“self.xlApp.Visible can not set?”一样产生错误。 这总是发生在一个循环中,就像:

 for fname in filelist: xlbook = XlsClass(fname) #do something 

然后我检查了我的'windowstasksmanager'并注意到这一点

 xlbook = Dispatch('Excel.Application') 

将创build一个名为“EXCEL.EXE * 32”的进程。 当我input'xlbook.Quit()'的过程还在那里!? 那么这个残留过程可能是'不能设置'的错误吗? 在我把这个function叫做“Dispatch”之后,我怎么能完全closures它呢?

 del xlbook 

无法杀死进程,所以它是如何工作的?

英语不好,等待帮助….谢谢。

================================================

2014/3/10:我再次捕获错误并捕获回溯…

 Traceback (most recent call last): File "C:\work_daily\work_RecPy\__RecLib\XlsClass.py", line 9, in __init__ self.xlApp.Visible = Visible File "C:\Program Files\python33\lib\site-packages\win32com\client\dynamic.py", line 576, in __setattr__ raise AttributeError("Property '%s.%s' can not be set." % (self._username_,attr)) AttributeError: Property 'Excel.Application.Visible' can not be set. 

我尝试del self.xlAppxlbook = None创build一个新的XlsClass()之前,但似乎不工作…

这可能是由于python的垃圾收集:每次通过循环创build一个XlsClass; 当一个迭代结束时,XlsClass的实例不再被引用,因此它可用于垃圾收集,但是这可能不会立即发生。 所以下一次通过循环你发出一个新的Excel,但前一个可能不完全closures。 在下一次迭代之前尝试强制垃圾回收:

 for fname in filelist: xlbook = XlsClass(fname) #do something xlbook = None gc.collect() 

更新:

如果这不起作用,您可以尝试附加到正在运行的实例,即一旦分派,不要closures应用程序,只需closures工作簿。 在这种情况下,你可能会想要做这样的事情:

 class XlsClass: def __init__(self, xlApp, filename=None ,*,Visible=False ,Alerts=False): self.xlApp = xlApp self.xlApp.Visible = Visible ... def otherMethod(self): # .... def close(self): self.xlBook.Close() self.xlBook = None self.xlApp = None # don't do anything with self.xlApp or self xlApp = win32com.client.Dispatch('Excel.Application') for fname in filelist: xlbook = XlsClass(xlApp, fname) # do something with xlbook xlbook.close() 

请注意,最好是明确closures本书,而不是等待__del__被垃圾收集器执行。

此外,您可以使用win32com.client.GetObject (filename) ,如果存在的话将获得现有的实例,如果不存在,将自动创build一个; 你可以把GetObject放在__init__ 。 在这种情况下, 如果在退出脚本之前打开 Excel,请执行最后的GetActiveObject (请参阅Python / win32com – 检查程序是否打开 ),然后Close Excel 。 在我的win32com脚本中,我检查脚本启动时Excel是否已经在运行,如果是的话,我打印一个错误,要求用户closures,以防万一用户打开Excel书籍,让他们清理并退出,以便从已知状态开始。