【问题标题】:a bytes-like object is required, not 'str' despite i provided byte object尽管我提供了字节对象,但需要一个类似字节的对象,而不是“str”
【发布时间】:2019-12-21 22:01:54
【问题描述】:

我正在尝试将字符串写入以“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

【问题讨论】:

  • 您能否删除try/except 并让任何异常发生而不是捕获和打印它?然后显示堆栈跟踪,以便我们可以看到错误的来源。
  • 什么是rows_list?我会假设一个字符串列表,但你能确认一下吗?发布其中的一部分会有所帮助。请参阅minimal reproducible example 了解更多指示。
  • @mkrieger1 Traceback(最近一次调用最后):文件“”,第 1 行,在 文件“c:\pythonsv\icelake\debug\domains\ice\platform_config_generation.py ",第 81 行,在 write_max_pstate_config_csv filewriter.writerow([row.encode("utf-8")]) TypeError: a bytes-like object is required, not 'str'
  • @wjandrea 你是对的 rows_list 它只是字符串列表 rows_list=[] rows_list.append('plimit') rows_list.append('#i_pstate')

标签: python-3.x csv unicode


【解决方案1】:

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

虽然 Python 2 中的后期工作可以通过使用 unicode 以及默认情况下在文件开头使用 from __future__ import unicode_literals 来正确处理文本作为文本,但 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()  

【讨论】:

    【解决方案2】:

    我终于在open函数上使用了if else语句,就够了

    import six
    if not six.PY2:#python3
            csvfile=open(output_file_path, 'w',newline='')
        else:#python2    
            csvfile=open(output_file_path, 'wb')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      相关资源
      最近更新 更多