csv类编写器:需要类似字节的对象,而不是“str”

2024-09-20 23:02:58 发布

您现在位置:Python中文网/ 问答频道 /正文

对于个人项目,我正试图将paterns包升级到Python 3。 实际上,我正在运行测试:db.py,但在csv类上的“uu init\uu.py”文件中,我遇到了以下错误:

这是save()函数的代码段: 在这里,我们将s作为一个BytesIO()流,因此要求函数将字节流到一个selfcsv文件。 错误来自行:

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来传递字节的,我检查了这个,它确实这样做了,但是不知怎么的,在它的转换列表中,它变为'str'。 如果我将s编码改为StringsIO,那么抱怨来自

 f.write(BOM_UTF8)

任何帮助都将不胜感激。

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())

Tags: orcsvthenameinselfnonefor
1条回答
网友
1楼 · 发布于 2024-09-20 23:02:58

您可能试图写入BytesIO对象,但csv.writer()只处理字符串中的内容。从^{} writer objects documentation

A row must be an iterable of strings or numbers

强调我的。^{}还需要一个文本文件来写入;对象生成字符串:

[...] converting the user’s data into delimited strings on the given file-like object.

请改用^{} object,或者将BytesIO对象包装在^{} object中,以便为您处理编码。不管怎样,您都需要将Unicode文本传递给csv.writer()

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

失败是一个独立的问题。f以文本模式('wt')打开,因此需要字符串,而不是bytes。如果你想写 文本到开始时编码为UTF-8并带有UTF-8 BOM的文件在打开文件时可以使用utf-8-sig编码:

open(path, 'w', encoding='utf-8-sig')

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

相关问题 更多 >

    热门问题