我正在尝试使用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()
我使用线程的原因是因为我使用多个API(google,yahoo,openstreetmap API,bing)尝试规范化地址并进行比较。任何人都可以帮助我,当我使用线程而不是正常的函数调用时,为什么我无法写入工作表。
答案 0 :(得分:1)
谨慎使用! XlsxWriter不是线程安全的。我发现如果你使用in_memory选项,它将使用SharedStrings并最终写入意外的单元格。我创建了一张机票atm:
来自XlsxWriter作者的更新:
_get_shared_string_index()
中的SharedStrings
方法并非如此 线程安全。该类中的其他方法应该是因为它们 仅从Workbook
调用(对此应该只有一个唯一的 每个xlsxwriter对象的实例)或通过Workbook
析构函数(当 应该连接工作表线程并停止活动。我发现如果我使用in_memory选项,XlsxWriter将使用SharedStrings
无论您是否使用,都可以调用SharedStrings类 in_memory与否。 in_memory选项与临时使用有关 文件而不是SharedStrings(参见文档)。
如果您希望避免使用SharedStrings,从而避免锁定,那么 可以使用constant_memory模式。有一些警告 但是:数据需要按行列顺序编写,您无法使用 add_table()或merge_range()。请参阅Contructor文档(上面的链接)和 也在使用记忆和表现。
XlsxWriter还有什么需要我担心的吗?
可能,但没有任何想到的东西。
答案 1 :(得分:0)
我已经在函数末尾使用threading.join()解决了它。为什么我们需要使用join()可以从这个link中理解。以下代码对我有用。
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