关于python3.5中的bytes-like object和str

yb775802151 2016-11-06 07:11:48
最近学scrapy爬虫的时候,用CsvItemExporter将Item写入csv文件时,报错
引用
TypeError: write() argument must be str, not bytes

代码如下:
class StockPipelineCSV(object):

def open_spider(self,spider):
self.file = open('stocks_01.csv', 'w')
self.exporter = CsvItemExporter(self.file)
self.exporter.start_exporting()

def close_spider(self,spider):
self.exporter.finish_exporting()
self.file.close()

def process_item(self, item, spider):
self.exporter.export_item(item)
return item

然后找到exporters的CsvItemExporter类中的export_item()函数以及其他相关函数:
#exporters.py
def export_item(self, item):
if self._headers_not_written:
self._headers_not_written = False
self._write_headers_and_set_fields_to_export(item)

fields = self._get_serialized_fields(item, default_value='',
include_empty=True)
values = list(self._build_row(x for _, x in fields))
self.csv_writer.writerow(values)

def _build_row(self, values):
for s in values:
try:
yield to_native_str(s, self.encoding)
except TypeError:
yield s

其中用到了
#python.py
def to_native_str(text, encoding=None, errors='strict'):
""" Return str representation of `text`
(bytes in Python 2.x and unicode in Python 3.x). """
if six.PY2:
return to_bytes(text, encoding, errors)
else:
return to_unicode(text, encoding, errors)

发现这里没问题已经将item转换成存放str对象的一个list了,不知道问题究竟出在哪里?scrapy是初学,不知道是不是scrapy的itempipeline.py代码的问题?
网上查了半天说是要用w+b二进制方式打开,这样确实不会报错了,但写进去之后是乱码,顺序也随机(这个可能是我settings.py里没有设置)
然后我自己写了小程序测试,自己open一个csv文件,以w+b打开
# coding: utf-8

import csv

csvfile = open('D://t.csv', 'w+b')
writer = csv.writer(csvfile)
writer.writerow([str.encode('列1'), str.encode('列2'), str.encode('列3')])

data = [
str.encode('值1'), str.encode('值2'), str.encode('值3')
]
writer.writerow(data)

csvfile.close()

结果报错:
引用
TypeError: a bytes-like object is required, not 'str'

但我明明把他转换成bytes了啊。最后用w方式写入,正常了。但对bytes-like object和str者二者很困惑。

csdn新人,不太会用,在技术问答那里也提了同样的问题。
...全文
35168 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
yb775802151 2016-11-09
  • 打赏
  • 举报
回复
引用 8 楼 sprawling 的回复:
[quote=引用 2 楼 yb775802151 的回复:] 求解答啊。。
那你在py3里面运行,调用的是to_unicode,根据字面意思是转换成了unicode, 而write是要的str类型的数据,这不是有问题吗?[/quote] py3中的str格式的定义不就是Unicode编码的字符串吗?
sprawling 2016-11-09
  • 打赏
  • 举报
回复
引用 2 楼 yb775802151 的回复:
求解答啊。。
那你在py3里面运行,调用的是to_unicode,根据字面意思是转换成了unicode, 而write是要的str类型的数据,这不是有问题吗?
yb775802151 2016-11-08
  • 打赏
  • 举报
回复
求解答啊。。
yb775802151 2016-11-08
  • 打赏
  • 举报
回复
引用 6 楼 sprawling 的回复:
[quote=引用 5 楼 yb775802151 的回复:] [quote=引用 3 楼 raining 的回复:] 不是写得很清楚么?需要str,你给了bytes. TypeError: write() argument must be str, not bytes
但是我看exporters.py里export_item()的实现(上面贴了代码),看到里面把用to_natice_str把byte转换成str了,实现方法在python.py里面了,这个方法的注释是""" Return str representation of `text` (bytes in Python 2.x and unicode in Python 3.x). """返回被转换文本的str表示,在python2.x中是bytes,在python3.x中是unicode,所以不应该给我报这个错误啊。我想知道问题出在哪里[/quote] 不知道py3里面怎样处理,但是在 py2里面unicode跟str不是同一种类型的数据.[/quote] 对,to_native_str对py2和py3的处理是不一样的。py3中byte是ascii,str是unicode。我上面贴了代码:

#python.py
def to_native_str(text, encoding=None, errors='strict'):
""" Return str representation of `text`
(bytes in Python 2.x and unicode in Python 3.x). """
if six.PY2:
    return to_bytes(text, encoding, errors)
else:
    return to_unicode(text, encoding, errors)
sprawling 2016-11-08
  • 打赏
  • 举报
回复
引用 5 楼 yb775802151 的回复:
[quote=引用 3 楼 raining 的回复:] 不是写得很清楚么?需要str,你给了bytes. TypeError: write() argument must be str, not bytes
但是我看exporters.py里export_item()的实现(上面贴了代码),看到里面把用to_natice_str把byte转换成str了,实现方法在python.py里面了,这个方法的注释是""" Return str representation of `text` (bytes in Python 2.x and unicode in Python 3.x). """返回被转换文本的str表示,在python2.x中是bytes,在python3.x中是unicode,所以不应该给我报这个错误啊。我想知道问题出在哪里[/quote] 不知道py3里面怎样处理,但是在 py2里面unicode跟str不是同一种类型的数据.
yb775802151 2016-11-08
  • 打赏
  • 举报
回复
引用 3 楼 raining 的回复:
不是写得很清楚么?需要str,你给了bytes. TypeError: write() argument must be str, not bytes
但是我看exporters.py里export_item()的实现(上面贴了代码),看到里面把用to_natice_str把byte转换成str了,实现方法在python.py里面了,这个方法的注释是""" Return str representation of `text` (bytes in Python 2.x and unicode in Python 3.x). """返回被转换文本的str表示,在python2.x中是bytes,在python3.x中是unicode,所以不应该给我报这个错误啊。我想知道问题出在哪里
yb775802151 2016-11-08
  • 打赏
  • 举报
回复
但是我看exporters.py里export_item()的实现(上面贴了代码),看到里面把用to_natice_str把byte转换成str了,实现方法在python.py里面了,这个方法的注释是""" Return str representation of `text` (bytes in Python 2.x and unicode in Python 3.x). """返回被转换文本的str表示,在python2.x中是bytes,在python3.x中是unicode,所以不应该给我报这个错误啊。我想知道问题出在哪里
raining 2016-11-08
  • 打赏
  • 举报
回复
不是写得很清楚么?需要str,你给了bytes. TypeError: write() argument must be str, not bytes
yb775802151 2016-11-06
  • 打赏
  • 举报
回复
不好意思,最后一句没有描述准确,我是改为w方式打开文件,并且去掉了str.encode(),这样写入才正常了。但是不理解为什么之前的方式会报错。

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧