首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >csv类编写器:需要一个类似字节的对象,而不是'str‘。

csv类编写器:需要一个类似字节的对象,而不是'str‘。
EN

Stack Overflow用户
提问于 2017-04-14 13:56:11
回答 1查看 16.9K关注 0票数 4

对于一个个人项目,我正在尝试将父子包升级到Python3。实际上,我正在运行test:db.py,但是在csv类上的'__init__.py'文件中有以下错误:

这是保存()函数的代码片段:在那里,我们将定义为BytesIO()流,因此函数被要求将字节流流到一个self csv文件中。错误来自行:

代码语言:javascript
运行
复制
w.writerows([[csv_header_encode(name, type) for name, type in self.fields]])

TypeError: a bytes-like object is required, not 'str' ( below, also the code for this function)

假设csv_header_encode可以传递字节,我检查了它,但不知怎么的,它在转换为list时更改为'str‘。如果我将编码更改为StringsIO,那么抱怨来自

代码语言:javascript
运行
复制
 f.write(BOM_UTF8)

任何帮助都将不胜感激。

代码语言:javascript
运行
复制
def save(self, path, separator=",", encoder=lambda v: v, headers=False, password=None, **kwargs):
    """ Exports the table to a unicode text file at the given path.
        Rows in the file are separated with a newline.
        Columns in a row are separated with the given separator (by default, comma).
        For data types other than string, int, float, bool or None, a custom string encoder can be given.
    """
    # Optional parameters include all arguments for csv.writer(), see:
    # http://docs.python.org/library/csv.html#csv.writer
    kwargs.setdefault("delimiter", separator)
    kwargs.setdefault("quoting", csvlib.QUOTE_ALL)
    # csv.writer will handle str, int, float and bool:
    s = BytesIO()
    w = csvlib.writer(s,  **kwargs)
    if headers and self.fields is not None:
        w.writerows([[csv_header_encode(name, type) for name, type in self.fields]])
    w.writerows([[encode_utf8(encoder(v)) for v in row] for row in self])
    s = s.getvalue()
    s = s.strip()
    s = re.sub("([^\"]|^)\"None\"", "\\1None", s)
    s = (s if not password else encrypt_string(s, password)).encode('latin-1')
    f = open(path, "wt")
    f.write(BOM_UTF8)
    f.write(s)
    f.close()

def csv_header_encode(field, type=STRING):
    # csv_header_encode("age", INTEGER) => "age (INTEGER)".
    t = re.sub(r"^varchar\(.*?\)", "string", (type or ""))
    t = t and " (%s)" % t or ""
    return "%s%s" % (encode_utf8(field or ""), t.upper())
EN

回答 1

Stack Overflow用户

发布于 2017-04-14 13:58:26

您可能试图写入BytesIO对象,但csv.writer()只处理字符串。来自 writer objects documentation

行必须是字符串或数字的可迭代

强调我的。csv.writer()还需要一个要写入的文本文件;对象生成字符串:

..。在给定的类文件对象上将用户的数据转换为分隔字符串

要么使用 object,要么将BytesIO对象包装在 object中,为您处理编码。无论哪种方式,您都需要将Unicode文本传递给csv.writer()

因为稍后您将再次将s.getvalue()数据作为字符串处理(使用定义为字符串的正则表达式,并使用拉丁文-1的编码),因此您可能希望将其写入文本文件(所以是StringIO)。

f.write(BOM_UTF8)失败是另一个问题。f是以文本模式('wt')打开的,因此需要字符串,而不是bytes。如果要将文本写入以UTF-8编码的文件,并在开始时使用UTF-8 BOM,则可以在打开该文件时使用utf-8-sig编码:

代码语言:javascript
运行
复制
open(path, 'w', encoding='utf-8-sig')

通常,您似乎以所有错误的方式混合字节和字符串。尽可能长地保留文本作为文本,并且只在最后的可能时刻进行编码。在这里,当写入位于path位置的文件时,您可以将编码完全留给文件对象。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43413018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档