Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用线程时无法使用xlsxwriter进行写入_Python_Multithreading_Excel_Xlsxwriter - Fatal编程技术网

Python 使用线程时无法使用xlsxwriter进行写入

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.

我正在尝试使用python中的xlswriter包将位置地址写入excel工作表。我面临的问题是,当我尝试使用线程运行函数时,值不会写入工作表。请参阅下面的代码:这里是一个包含所有原始地址的列表

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
方法,因为末尾没有
()
。无论如何,在您的真实代码中肯定还有其他事情没有显示在这里。