多线程与多进程

在版本 0.13.0 中新增。

多线程

尽管 xlwings 从技术上来说不是线程安全的,但只要您至少使用 v0.13.0,并遵守一个简单规则,仍然可以轻松地在多线程中使用它:不要将 xlwings 对象传递给线程。此规则在 macOS 上不是必要条件,但如果希望程序跨平台运行,仍建议遵循该规则。

考虑以下示例,这将不会正常工作:

import threading
from queue import Queue
import xlwings as xw

num_threads = 4


def write_to_workbook():
    while True:
        myrange = q.get()
        myrange.value = myrange.address
        print(myrange.address)
        q.task_done()


q = Queue()

for i in range(num_threads):
    t = threading.Thread(target=write_to_workbook)
    t.daemon = True
    t.start()

for cell in ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10']:
    # THIS DOESN'T WORK - passing xlwings objects to threads will fail!
    myrange = xw.Book('Book1.xlsx').sheets[0].range(cell)
    q.put(myrange)

q.join()

要使其正常工作,只需要在线程中完全限定单元格引用,而不是传递一个Book对象:

import threading
from queue import Queue
import xlwings as xw

num_threads = 4


def write_to_workbook():
    while True:
        cell_ = q.get()
        xw.Book('Book1.xlsx').sheets[0].range(cell_).value = cell_
        print(cell_)
        q.task_done()


q = Queue()

for i in range(num_threads):
    t = threading.Thread(target=write_to_workbook)
    t.daemon = True
    t.start()

for cell in ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10']:
    q.put(cell)

q.join()

多进程

注意

多进程仅支持 Windows!

多进程与多线程适用相同的规则,这里是一个正常工作的示例:

from multiprocessing import Pool
import xlwings as xw


def write_to_workbook(cell):
    xw.Book('Book1.xlsx').sheets[0].range(cell).value = cell
    print(cell)


if __name__ == '__main__':
    with Pool(4) as p:
        p.map(write_to_workbook,
              ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10'])