You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用多线程时xlwings无法正确更新全局变量的问题排查

问题描述

我通过多线程创建xlwings工作簿后,打印全局变量时触发COM错误,代码如下:

import xlwings as xw
import threading
workbook = ""

def function1():
    t1 = threading.Thread(target=function2)
    t1.start()
    t1.join()

def function2():
    global workbook
    workbook = xw.Book()

function1()
print(workbook)

运行后报错:

Traceback (most recent call last):
  File "c:\Users\rakesh.ramanjulu\Documents\Python Projects\Vendor ScoreCard Accuracy Final\test.py", line 51, in <module>
    print (workbook)
  File "C:\Users\rakesh.ramanjulu\AppData\Local\Programs\Python\Python312\Lib\site-packages\xlwings\main.py", line 1288, in __repr__
    return "<Book [{0}]>".format(self.name)
                                 ^^^^^^^^^
  File "C:\Users\rakesh.ramanjulu\AppData\Local\Programs\Python\Python312\Lib\site-packages\xlwings\main.py", line 1105, in name
    return self.impl.name
           ^^^^^^^^^^^^^^
  File "C:\Users\rakesh.ramanjulu\AppData\Local\Programs\Python\Python312\Lib\site-packages\xlwings\_xlwindows.py", line 837, in name
    return self.xl.Name
           ^^^^^^^^^^^^
  File "C:\Users\rakesh.ramanjulu\AppData\Local\Programs\Python\Python312\Lib\site-packages\xlwings\_xlwindows.py", line 199, in __getattr__
    v = getattr(self._inner, item)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\rakesh.ramanjulu\AppData\Local\Programs\Python\Python312\Lib\site-packages\xlwings\_win32patch.py", line 55, in __getattr__
    return getattr(d, attr)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\rakesh.ramanjulu\AppData\Local\Programs\Python\Python312\Lib\site-packages\win32com\client\__init__.py", line 585, in __getattr__
    return self._ApplyTypes_(*args)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\rakesh.ramanjulu\AppData\Local\Programs\Python\Python312\Lib\site-packages\win32com\client\__init__.py", line 574, in _ApplyTypes_
    self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pywintypes.com_error: (-2147220995, 'Object is not connected to server', None, None)

之前用多线程更新全局变量从未出现问题,不清楚该如何解决这个报错。

问题原因与解决方法

原因

这不是全局变量的问题,核心在于Windows下xlwings依赖的Excel COM对象不支持跨线程访问。子线程创建工作簿对象后,线程结束时其关联的COM上下文会被销毁,导致主线程访问该对象时,它已经与Excel服务器断开连接,从而触发"Object is not connected to server"错误。

解决方案

方案1:将Excel操作移至主线程

如果业务逻辑允许,直接在主线程中创建和访问Excel对象:

import xlwings as xw
import threading
workbook = ""

def function1():
    global workbook
    workbook = xw.Book()

function1()
print(workbook)

方案2:在子线程内完成所有Excel操作

若必须使用多线程,所有涉及该工作簿对象的操作都要放在创建它的子线程中,避免跨线程传递对象:

import xlwings as xw
import threading

def function2():
    workbook = xw.Book()
    # 在此完成所有对workbook的读写、打印等操作
    print(workbook)

def function1():
    t1 = threading.Thread(target=function2)
    t1.start()
    t1.join()

function1()

方案3:显式管理COM上下文(进阶)

通过pythoncom模块在子线程内初始化和释放COM上下文,同时显式控制Excel App的生命周期,可一定程度避免上下文提前销毁,但仍需注意不要跨线程访问对象:

import xlwings as xw
import threading
import pythoncom

def function2():
    # 初始化子线程的COM上下文
    pythoncom.CoInitialize()
    xl_app = xw.App(visible=True)
    workbook = xl_app.Book()
    # 在此完成所有Excel操作
    print(workbook)
    # 释放COM上下文
    pythoncom.CoUninitialize()

def function1():
    t1 = threading.Thread(target=function2)
    t1.start()
    t1.join()

function1()

内容的提问来源于stack exchange,提问作者Rakesh RAMANJULU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:10:12