在 python 中使用 `yield` 关键字的上下文
context for using `yield` keyword in python
我有以下程序可以从网站上抓取数据。我想通过使用带有 yield 的生成器而不是连续多次调用 generate_url
和 call_me
来改进下面的代码。本练习的目的是正确理解 yield
及其使用环境。
import requests
import shutil
start_date='03-03-1997'
end_date='10-04-2015'
yf_base_url ='http://real-chart.finance.yahoo.com/table.csv?s=%5E'
index_list = ['BSESN','NSEI']
def generate_url(index, start_date, end_date):
s_day = start_date.split('-')[0]
s_month = start_date.split('-')[1]
s_year = start_date.split('-')[2]
e_day = end_date.split('-')[0]
e_month = end_date.split('-')[1]
e_year = end_date.split('-')[2]
if (index == 'BSESN') or (index == 'NSEI'):
url = yf_base_url + index + '&a={}&b={}&c={}&d={}&e={}&f={}'.format(s_day,s_month,s_year,e_day,e_month,e_year)
return url
def callme(url,index):
print('URL {}'.format(url))
r = requests.get(url, verify=False,stream=True)
if r.status_code!=200:
print "Failure!!"
exit()
else:
r.raw.decode_content = True
with open(index + "file.csv", 'wb') as f:
shutil.copyfileobj(r.raw, f)
print "Success"
if __name__ == '__main__':
url = generate_url(index_list[0],start_date,end_date)
callme(url,index_list[0])
url = generate_url(index_list[1],start_date,end_date)
callme(url,index_list[1])
有多种选择。您可以使用 yield 迭代 URL。或者超过请求对象。
如果您的 index_list
很长,我建议让出 URL。
因为这样你就可以使用 multiprocessing.Pool
来映射一个函数,该函数执行请求并将输出保存在这些 URL 上。这将并行执行它们,可能会使其速度更快(假设您有足够的网络带宽,并且 yahoo finance 不会限制连接)。
yf ='http://real-chart.finance.yahoo.com/table.csv?s=%5E'
'{}&a={}&b={}&c={}&d={}&e={}&f={}'
index_list = ['BSESN','NSEI']
def genurl(symbols, start_date, end_date):
# assemble the URLs
s_day, s_month, s_year = start_date.split('-')
e_day, e_month, e_year = end_date.split('-')
for s in symbols:
url = yf.format(s, s_day,s_month,s_year,e_day,e_month,e_year)
yield url
def download(url):
# Do the request, save the file
p = multiprocessing.Pool()
rv = p.map(download, genurl(index_list, '03-03-1997', '10-04-2015'))
如果我没理解错的话,你想知道的是如何更改代码,以便可以将最后一部分替换为
if __name__ == '__main__':
for url in generate_url(index_list,start_date,end_date):
callme(url,index)
如果这是正确的,您需要更改 generate_url
,而不是 callme
。更改 generate_url
是相当机械的。将第一个参数 index_list
替换为 index
,将函数体包裹在 for index in index_list
循环中,并将 return url
更改为 yield url
.
你不需要改变 callme
因为你永远不想说 for call in callme(...)
这样的话。除了正常的函数调用外,您不会用它做任何事情。
我有以下程序可以从网站上抓取数据。我想通过使用带有 yield 的生成器而不是连续多次调用 generate_url
和 call_me
来改进下面的代码。本练习的目的是正确理解 yield
及其使用环境。
import requests
import shutil
start_date='03-03-1997'
end_date='10-04-2015'
yf_base_url ='http://real-chart.finance.yahoo.com/table.csv?s=%5E'
index_list = ['BSESN','NSEI']
def generate_url(index, start_date, end_date):
s_day = start_date.split('-')[0]
s_month = start_date.split('-')[1]
s_year = start_date.split('-')[2]
e_day = end_date.split('-')[0]
e_month = end_date.split('-')[1]
e_year = end_date.split('-')[2]
if (index == 'BSESN') or (index == 'NSEI'):
url = yf_base_url + index + '&a={}&b={}&c={}&d={}&e={}&f={}'.format(s_day,s_month,s_year,e_day,e_month,e_year)
return url
def callme(url,index):
print('URL {}'.format(url))
r = requests.get(url, verify=False,stream=True)
if r.status_code!=200:
print "Failure!!"
exit()
else:
r.raw.decode_content = True
with open(index + "file.csv", 'wb') as f:
shutil.copyfileobj(r.raw, f)
print "Success"
if __name__ == '__main__':
url = generate_url(index_list[0],start_date,end_date)
callme(url,index_list[0])
url = generate_url(index_list[1],start_date,end_date)
callme(url,index_list[1])
有多种选择。您可以使用 yield 迭代 URL。或者超过请求对象。
如果您的 index_list
很长,我建议让出 URL。
因为这样你就可以使用 multiprocessing.Pool
来映射一个函数,该函数执行请求并将输出保存在这些 URL 上。这将并行执行它们,可能会使其速度更快(假设您有足够的网络带宽,并且 yahoo finance 不会限制连接)。
yf ='http://real-chart.finance.yahoo.com/table.csv?s=%5E'
'{}&a={}&b={}&c={}&d={}&e={}&f={}'
index_list = ['BSESN','NSEI']
def genurl(symbols, start_date, end_date):
# assemble the URLs
s_day, s_month, s_year = start_date.split('-')
e_day, e_month, e_year = end_date.split('-')
for s in symbols:
url = yf.format(s, s_day,s_month,s_year,e_day,e_month,e_year)
yield url
def download(url):
# Do the request, save the file
p = multiprocessing.Pool()
rv = p.map(download, genurl(index_list, '03-03-1997', '10-04-2015'))
如果我没理解错的话,你想知道的是如何更改代码,以便可以将最后一部分替换为
if __name__ == '__main__':
for url in generate_url(index_list,start_date,end_date):
callme(url,index)
如果这是正确的,您需要更改 generate_url
,而不是 callme
。更改 generate_url
是相当机械的。将第一个参数 index_list
替换为 index
,将函数体包裹在 for index in index_list
循环中,并将 return url
更改为 yield url
.
你不需要改变 callme
因为你永远不想说 for call in callme(...)
这样的话。除了正常的函数调用外,您不会用它做任何事情。