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

最近学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了啊。最后换了一种方式,去掉str.encode(),用w方式写入,正常了。但对bytes-like object和str者二者很困惑,不理解之前的方式为什么会报错。

1个回答

python3中,byte字符串就是ansi字符串。str是unicode字符串。所以写文件的时候需要注意文件编码格式

yb775802151
yb775802151 我最后没有写准确:我是将写文件方式改为w,然后删去str.encode()结果正常了,这个我可以理解,将字符以写的方式写入文件。但把字符转为字节去以二进制写为什么还是会提示我说需要二进制对象?
接近 4 年之前 回复
yb775802151
yb775802151 那我后一个以二进制方式写csv文件用str.encode()把str转换成byte了,为什么会报TypeError: a bytes-like object is required, not 'str'错误呢?
接近 4 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐