【问题标题】:csv.writer prints "bytes" with prefix and quotescsv.writer 打印带有前缀和引号的“字节”
【发布时间】:2016-12-10 18:21:10
【问题描述】:

在 Python 2 中,这段代码符合我的预期:

import csv
import sys

writer = csv.writer(sys.stdout)
writer.writerow([u'hello', b'world'])

打印出来:

hello,world

但在 Python 3 中,bytes 打印时带有前缀和引号:

hello,b'world'

由于 CSV 是一种通用数据交换格式,并且除了 Python 之外没有其他系统知道 b'' 是什么,我需要禁用此行为。但我还没弄清楚怎么做。

当然,我可以首先在所有bytes 上使用str.decode,但这既不方便又低效。我真正想要的是将文字字节写入文件,或者将编码(例如'ascii')传递给csv.writer(),以便它知道如何解码它看到的任何bytes 对象。

【问题讨论】:

    标签: python python-3.x csv python-unicode


    【解决方案1】:

    我认为没有任何方法可以避免在 Python 3 中使用 csv 模块将字节字符串显式转换为 unicode 字符串。在 Python 2 中,它们被隐式转换为 ASCII。

    为了使这更容易,您可以有效地继承csv.writer 或包装对象,如下所示,这将使过程更方便。

    import csv
    
    class CSV_Writer(object):
        def __init__(self, *args, **kwrds):
            self.csv_writer = csv.writer(*args, **kwrds)
    
        def __getattr__(self, name):
            return getattr(self.csv_writer, name)
    
        def writerow(self, row):
            self.csv_writer.writerow(str(v, encoding='utf-8') if isinstance(v, bytes) 
                                            else v for v in row)
    
        def writerows(self, rows):
            for row in rows:
                self.writerow(row)
    
    
    with open('bytes_test.csv', 'w', newline='') as file:
        writer = CSV_Writer(file)
        writer.writerow([u'hello', b'world'])
    

    【讨论】:

    • 字节字符串和 unicode 字符串在 Python 2 中也是两种不同的类型。 Python 2 只允许使用默认的ascii 编解码器进行隐式转换。
    【解决方案2】:

    csv 在 Python 3 中写入文本文件并需要 Unicode(文本)字符串。

    csv 在 Python 2 中写入二进制文件并期望字节字符串,但允许使用默认的 ascii 编解码器将 Unicode 字符串隐式编码为字节字符串。 Python 3 不允许隐式转换,所以你无法真正避免它:

    #!python3
    import csv
    import sys
    writer = csv.writer(sys.stdout)
    writer.writerow(['hello', b'world'.decode()])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-04-25
      • 2020-03-18
      • 2013-05-20
      • 2019-10-28
      • 2017-02-25
      • 2013-06-14
      • 1970-01-01
      相关资源
      最近更新 更多