【发布时间】:2013-05-04 13:38:46
【问题描述】:
使用namedtuple 文档示例作为我在 Python 3.3 中的模板,我有以下代码来下载 csv 并将其转换为一系列 namedtuple 子类实例:
from collections import namedtuple
from csv import reader
from urllib.request import urlopen
SecurityType = namedtuple('SecurityType', 'sector, name')
url = 'http://bsym.bloomberg.com/sym/pages/security_type.csv'
for sec in map(SecurityType._make, reader(urlopen(url))):
print(sec)
这会引发以下异常:
Traceback (most recent call last):
File "scrap.py", line 9, in <module>
for sec in map(SecurityType._make, reader(urlopen(url))):
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
我知道问题在于 urlopen 返回的是字节而不是字符串,并且我需要在某个时候对输出进行解码。这是我现在的做法,使用 StringIO:
from collections import namedtuple
from csv import reader
from urllib.request import urlopen
import io
SecurityType = namedtuple('SecurityType', 'sector, name')
url = 'http://bsym.bloomberg.com/sym/pages/security_type.csv'
reader_input = io.StringIO(urlopen(url).read().decode('utf-8'))
for sec in map(SecurityType._make, reader(reader_input)):
print(sec)
这听起来很有趣,因为我基本上是遍历字节缓冲区、解码、重新缓冲,然后遍历新的字符串缓冲区。有没有更 Pythonic 的方法可以在没有两次迭代的情况下做到这一点?
【问题讨论】:
-
嗯。我要推荐的(使用
TextIOWrapper)没有用,IMO 应该有。一些挖掘发现this bug (issue 16723),这似乎是问题所在。 -
@DSM:该补丁已在 2 月应用,因此最新的 3.x 版本包含它。您使用的是哪个版本的 3.x?
-
3.3.0.我喜欢保持最新状态,但距离 3.3.1 发布还不到一个月。 :^)
标签: python csv python-3.x namedtuple