<p>下面是我该怎么做的。它将产生你想要的输出。我已经重新格式化了一些代码,以便更好地适应stackoverflow上的代码列表框。棘手的部分是找出读入内存中矩阵的数据的<code>datacode</code>到{<cd2>}的映射。在</p>
<pre><code>import sys, csv, urllib2
class SmfImpl():
def __init__( self, ctx ):
self.ctx = ctx
self.csv_reader = ''
self.flag = ['Not Available', '']
self.ticker = 'XOM'
def getMorningKey(self, datacode):
return fetch_keyratios(self, datacode)
#these functions are not in the SmfImpl class because they're in a seperate file
def query_morningstar(self, url_ending):
MORNING_STAR = 'http://financials.morningstar.com/ajax/exportKR2CSV.html'
url = MORNING_STAR + '?&callback=?&t=XNYS:%s%s' % (self.ticker, url_ending)
req = urllib2.Request(url)
response = sniff_query(req)
response.readline()
return csv.reader(response)
def sniff_query(req):
try:
response = urllib2.urlopen(req)
except urllib2.URLError:
return 'Check Connection'
sniff = response.readline()
if str(sniff) == '':
return 'Not Available'
return response
def fetch_keyratios(self, datacode):
if datacode < 1 or datacode > 990:
return 'Invalid Datacode'
#check if we already have the data we need
if(self.flag[0] == 'Check Connection' or
self.flag[0] == 'Not Available' or self.flag[1] != self.ticker):
#query remote and check for errors
self.csv_reader = query_morningstar(self,
'&region=usa&culture=en-US&cur=USD&order=desc')
if(self.csv_reader == 'Check Connection' or
self.csv_reader == 'Not Available'):
self.flag[1] = ''
return self.csv_reader # actually response status message
else:
self.flag[0] = ''
self.flag[1] = self.ticker
# read entire dataset in memory skipping lines as neccessary
self.data = [row[1:] for row in self.csv_reader if len(row) == 12]
return sort_keyratios(self, datacode)
def sort_keyratios(self, datacode):
# convert datacode to row, column and return data in that position of list
row, col = divmod(datacode-1, 11)
return self.data[row][col]
if __name__ == "__main__":
smf = SmfImpl(sys.argv)
ticker = 'XOM'
for val in range(1, 24):
print ticker, val,':', smf.getMorningKey(val)
</code></pre>
<p>使用<code>csv.reader()</code>代替<code>csv.DictReader</code>,因为您并没有真正使用列/字段名。第一次调用<code>getMorningKey()</code>时,响应中的所有数据(除了少数第一行)都被读入并存储在一个列表列表中。以这种方式读取的每一行都应该是12个项目的列表,任何未跳过的项目都将被跳过。此外,为了使数据代码的映射更容易,只保存最后11个条目。结果是一个二维矩阵,其中行是行号,列是字段号。我创建的这个<a href="https://db.tt/brXXdOY3" rel="nofollow">web page</a>上显示了Exxon示例ticker的原始矩阵数据视图。在</p>
<p>正如您所看到的,这种方法极大地简化了逻辑,而且由于它将所有数据存储在内存中,因此它将在后续调用中重用,并使随机访问成为可能,而无需再次执行查询。在</p>
<p>输出如下:</p>
^{pr2}$