Python 使用线程时无法使用xlsxwriter进行写入
我正在尝试使用python中的xlswriter包将位置地址写入excel工作表。我面临的问题是,当我尝试使用线程运行函数时,值不会写入工作表。请参阅下面的代码:这里是一个包含所有原始地址的列表Python 使用线程时无法使用xlsxwriter进行写入,python,multithreading,excel,xlsxwriter,Python,Multithreading,Excel,Xlsxwriter,我正在尝试使用python中的xlswriter包将位置地址写入excel工作表。我面临的问题是,当我尝试使用线程运行函数时,值不会写入工作表。请参阅下面的代码:这里是一个包含所有原始地址的列表 import threading import xlsxwriter from geopy.geocoders import Nominatim geolocator = Nominatim() outputLocation = 'output.xlsx' workbook = xlsxwriter.
import threading
import xlsxwriter
from geopy.geocoders import Nominatim
geolocator = Nominatim()
outputLocation = 'output.xlsx'
workbook = xlsxwriter.Workbook(outputLocation)
w_sheet4 = workbook.add_worksheet('openstreet')
def openstreet():
p = 1
for row in rows: #rows consists of raw addresses
try:
rawAddress = str(" ".join(row[1].strip().split())) #here I am normalizing the addresses using openstreet api
location = geolocator.geocode(rawAddress)
w_sheet4.write(p, 1, rawAddress)
w_sheet4.write(p, 2, str(location.address))
except Exception as e:
print "OpenStreet", e
p += 1
t4 = threading.Thread(target=openstreet)
t4.start()
如果我不使用线程并通过调用它来运行函数,我就能够写入工作表。请参阅以下代码:
import threading
import xlsxwriter
from geopy.geocoders import Nominatim
geolocator = Nominatim()
outputLocation = 'output.xlsx'
workbook = xlsxwriter.Workbook(outputLocation)
w_sheet4 = workbook.add_worksheet('openstreet')
def openstreet():
p = 1
for row in rows: #rows consists of raw addresses
try:
rawAddress = str(" ".join(row[1].strip().split())) #here I am normalizing the addresses using openstreet api
location = geolocator.geocode(rawAddress)
w_sheet4.write(p, 1, rawAddress) #raw address
w_sheet4.write(p, 2, str(location.address)) #normalize address
except Exception as e:
print "OpenStreet", e
p += 1
#t4 = threading.Thread(target=openstreet)
#t4.start()
openstreet()
我之所以使用thread,是因为我使用了多个API(google、yahoo、openstreetmap API、bing)试图规范化地址并进行比较。当我使用线程而不是普通函数调用时,有人能帮我解释为什么我不能写入工作表。我已经用函数末尾的threading.join()解决了这个问题。我们需要使用join()的原因可以从这里理解。下面的代码适用于我
import threading
import xlsxwriter
from geopy.geocoders import Nominatim
geolocator = Nominatim()
outputLocation = 'output.xlsx'
workbook = xlsxwriter.Workbook(outputLocation)
w_sheet4 = workbook.add_worksheet('openstreet')
def openstreet():
p = 1
for row in rows: #rows consists of raw addresses
try:
rawAddress = str(" ".join(row[1].strip().split())) #here I am normalizing the addresses using openstreet api
location = geolocator.geocode(rawAddress)
w_sheet4.write(p, 1, rawAddress)
w_sheet4.write(p, 2, str(location.address))
except Exception as e:
print "OpenStreet", e
p += 1
t4 = threading.Thread(target=openstreet)
t4.start()
t4.join() #we need to use threading.join to make sure the thread function finishes before the main program exits
小心使用!XlsxWriter不是线程安全的。我发现,如果您使用in_内存选项,它将使用共享字符串,并最终写入意外的单元格。我创建了一个自动取款机: 从XlsxWriter作者处更新:
SharedStrings
中的\u get\u shared\u string\u index()
方法无效
线程安全。该类中的其他方法应为,因为它们是
仅从工作簿
调用(该工作簿应只有一个唯一的
每个xlsxwriter对象的实例)或通过工作簿
析构函数(当
应连接工作表线程并停止活动)
我发现如果我使用内存选项XlsxWriter将使用共享字符串
无论是否使用,都可以调用SharedStrings类
是否在记忆中。in_memory选项与临时内存的使用有关
文件,而不是共享字符串(请参阅文档)
如果您希望避免使用SharedString,从而避免锁定,您可以
可以使用恒定内存模式。对此有一些警告
不过:数据需要按行-列顺序写入,不能使用
添加表()或合并范围()。参见承包商文件(上面的链接)和
还可以使用内存和性能
XlsxWriter中还有什么我需要担心的吗
可能吧,但我想不起来
我忘了添加use threading.join到我的程序中。我已经回答了下面的问题。您可能需要添加
workbook.close()
来编写工作簿。您显示的代码中没有任何内容可以解释为什么需要调用t4.join()
,因为t4
是非守护进程线程,所以无论如何都应该调用t4.join()
。注意,您实际上并没有调用join
方法,因为末尾没有()
。无论如何,在您的真实代码中肯定还有其他事情没有显示在这里。