私は最近、いくつかのコードを python3 に書き直し、urllib.request.urlopen によって返されたバイトをデコードして csv.reader に渡すためのクリーンな pythonic ソリューションを探していました。
私は次のことを思いつきました:
import urllib.request
def fetch(symbol='IBM'):
kwargs = { 'symbol': symbol,
'start_month': '01',
'start_day': '01',
'start_year': '2002',
'end_month': '12',
'end_day': '31',
'end_year': '2012',
}
urlstring = 'http://ichart.finance.yahoo.com/table.csv?s={symbol}&a={start_month}&b={start_day}&c={start_year}&d={end_month}&e={end_day}&f={end_year}&g=d&ignore=.csv'.format(**kwargs)
data = [row for row in csv.reader(map(bytes.decode, urllib.request.urlopen(urlstring), ('iso-8859-1' for i in iter(lambda:0,1))))]
return data
より良い解決策があるかどうか疑問に思っていますか?基本的に、URL は csv ファイルを返します。Python 2.x では、urllib2 を使用して urllib2.urlopen() の戻り値を csv.reader() に渡すことができましたが、Python 3.x では元に戻るようになりました。バイトなので、応答を bytes.decode にマップし、それを csv.reader に渡します。しかし、これを行うためのより良い方法があるかどうか、または最適な解決策を探しているときに何かを見逃した可能性があるかどうかに興味がありますか?
返されたオブジェクトを別の関数に渡して反復する前にデコードする必要がある、このようなケースを処理する適切な Pythonic の方法は何ですか?
編集: イグナシオに感謝します!
あなたがくれたリンクを見ると、次の解決策が得られました。
data=[row for row in csv.reader(codecs.iterdecode(urllib.request.urlopen(urlstring),'iso-8859-1'))]
よりきれいに見えます。