首页 > 解决方案 > 尽管我提供了字节对象,但需要一个类似字节的对象,而不是“str”

问题描述

我正在尝试将字符串写入以“wb”模式打开的 csv 文件。尽管我向 csv writer 提供了一个字节对象,但我得到了上述错误,我使用 pdb 来确保我是对的

(Pdb) type(row.encode("utf-8"))
<class 'bytes'>

我知道我只能在“w”模式下打开它,但它应该与 python2.7 兼容,并且在 python 2.7 中,如果我用“w”打开文件,它会插入多余的空行。另外应该兼容我想了解我在这里做错了什么。

rows_list=[]
rows_list.append('plimit')
rows_list.append('#i_pstate')
csvfile=open(output_file_path, 'wb')    
try:
    filewriter = csv.writer(csvfile, delimiter=',',
                                quotechar='|', quoting=csv.QUOTE_MINIMAL)
    #import pdb;pdb.set_trace()
    for row in rows_list:
        filewriter.writerow([row.encode("utf-8")])
except Exception as ex:
    print ("error occurred '%s'"% (ex))  
    return -1
finally:
   csvfile.close()    

完整追溯:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\pythonsv\icelake\debug\domains\ice\platform_config_generation.py", line 81, in write_max_pstate_config_csv
    filewriter.writerow([row.encode("utf-8")])
TypeError: a bytes-like object is required, not 's

标签: python-3.xcsvunicode

解决方案


Python 2 和 Python 3 之间最大的区别在于它们处理文本的方式。在 Python 3 中,字符串被认为是字符序列,而在 Python 2 中,它们被认为是字节序列,其中“unicode”对象用于处理字符序列。

尽管 Python 2 中的后期工作可以通过使用 unicode,甚至默认情况下from __future__ import unicode_literals在文件开头使用 a 来正确处理文本作为文本,但 csv 模块特别难以处理 - 它不适用于“真实文本” " 在 Python 2 中,你刚刚遇到了这些困难。

因此,如果您的程序必须同时使用 Python 2 和 Python 3,并且在两者中都使用 CSV,我认为最好的方法是拥有一些状态变量,并为每种语言运行稍微不同的代码路径。

基本上,将程序中的所有数据作为 unicode(纯 Python 3 字符串,您可能会求助于from __future__ unicode_literals编写相同的 .py 文件)。

from __future__ import unicode_literals

if sys.version_info.major < 3:
    file_mode = "wb"
    prepare_text = lambda t: t.encode("utf-8")
else:
    file_mode = "wt"
    prepare_text = lambda t: t

rows_list=[]
rows_list.append('plimit')
rows_list.append('#i_pstate')
csvfile=open(output_file_path, file_mode)    

try:
    filewriter = csv.writer(csvfile, delimiter=prepare_text(','),
                            quotechar=prepare_text('|'), quoting=csv.QUOTE_MINIMAL)
    for row in rows_list:
        filewriter.writerow(prepare_text(field) for field in row)
except Exception as ex:
    print ("error occurred '%s'"% (ex))  
    return -1
finally:
   csvfile.close()  

推荐阅读