Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过python csv编写utf-8?(上一个答案不起作用)_Python_Python 2.7_Csv - Fatal编程技术网

通过python csv编写utf-8?(上一个答案不起作用)

通过python csv编写utf-8?(上一个答案不起作用),python,python-2.7,csv,Python,Python 2.7,Csv,In建议使用csv文档中的一些示例代码来处理这种情况 我无法修复该代码的问题,我想知道我做错了什么 以下是我的测试代码: # -*- coding: UTF-8 -*- import csv import codecs import csvutf8 # sample code from csv documentation. x = u'owner’s' with codecs.open('simpleout.txt', 'wb', 'UTF_8') as of: spamwriter

In建议使用csv文档中的一些示例代码来处理这种情况

我无法修复该代码的问题,我想知道我做错了什么

以下是我的测试代码:

# -*- coding: UTF-8 -*-
import csv
import codecs
import csvutf8  # sample code from csv documentation.
x = u'owner’s'
with codecs.open('simpleout.txt', 'wb', 'UTF_8') as of:
    spamwriter = csvutf8.UnicodeWriter(of)
    spamwriter.writerow([x])
csvutf8.py是我从文档中复制并粘贴代码的文件,它位于此消息的末尾

库中
codecdes.py
的错误消息为:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 5: ordinal not in range(128)
我能做些什么来让它工作

csvutf8.py

"""Helper classes to output UTF_8 through CSV in Python 2.x"""

import csv, codecs, cStringIO

class UTF8Recoder:
    """
    Iterator that reads an encoded stream and reencodes the input to UTF-8
    """
    def __init__(self, f, encoding):
        self.reader = codecs.getreader(encoding)(f)

    def __iter__(self):
        return self

    def next(self):
        return self.reader.next().encode("utf-8")

class UnicodeReader:
    """
    A CSV reader which will iterate over lines in the CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        f = UTF8Recoder(f, encoding)
        self.reader = csv.reader(f, dialect=dialect, **kwds)

    def next(self):
        row = self.reader.next()
        return [unicode(s, "utf-8") for s in row]

    def __iter__(self):
        return self

    class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)

UnicodeWriter
示例代码用于从
open
获取的纯字节文件,而不是从
codecs.open
(或
io.open
)获取的Unicode文件。最简单的修复方法是只使用
open
而不是
codec。在主脚本中打开

with open('simpleout.txt', 'wb') as of:

如果你打算在一个项目中使用CSVUFT8/COD>,你将从一年后回来,或者与其他同事一起工作,你可能想考虑在Sy-IntIt<方法中添加这样的测试,所以下次你犯这个错误时(你会),它会立即出现,并有一个更明显的错误:

if isinstance(f, (
     codecs.StreamReader, codecs.StreamWriter,
     codecs.StreamReaderWriter, io.TextIOBase)):
    raise TypeError(
        'Need plain bytes files, not {}'.format(f.__class__))

但是如果您打算坚持使用Python 2,*在掌握窍门之前,很难发现这些错误,因此您现在应该学习如何发现它们。下面是一些具有相同错误的简单代码:

data1 = u'[owner’s]'
data2 = data1.encode('utf-8')
data3 = data2.encode('utf-8')
在交互式解释器中进行测试,并查看每个中间步骤的repr、type等。您将看到
data2
str
,而不是
unicode
。这意味着它只是一堆字节。将一堆字节编码为UTF-8意味着什么?唯一有意义的**是使用默认编码(因为您没有设置任何其他内容,所以为ASCII)将这些字节解码为Unicode,这样就可以将其编码回字节

因此,当您看到其中一个关于ASCII的
UnicodeDecodeError
s时(您很确定您调用的是
encode
,而不是
decode
),通常就是这个问题。检查调用它的类型,它可能是
str
而不是
unicode
***


*我认为2018年仍然使用Python2是有一个很好的理由的。如果没有,答案就简单多了:只要使用Python3,整个问题就不可能解决(代码更简单,运行更快)

**如果你认为Python不去猜测你的意思会更有意义,并把这当成一个错误……你是对的,这也是Python 3存在的主要原因之一

***当然,您仍然需要弄清楚为什么在哪里有字节
您希望使用Unicode。有时这真的很愚蠢,就像你做了
u=s.decode('latin1')
,但是你一直用
s
而不是
u
。有时候会有点棘手,比如这个例子,你正在使用一个自动为你编码的库,但是你没有意识到。有时甚至更糟,比如你忘记解码网站上的一些文本,它整天都在默默运行,在运行到第一个带有斯拉夫名字的页面之前,创建了数千页的mojibake,最后出现了一个错误。

供将来参考:请确保你发布的代码实际上是你的代码(不能以这种方式缩进
类UnicodeWriter:
,否则导入
将失败,出现
语法错误
),并发布回溯,而不仅仅是错误(以便有人可以知道问题发生在何处)@Martin Evans。UnicodeWriter不是Python库中的一个模块,因此不可直接导入。相反,它是一些作为示例包含在编解码器文档中的代码。过去,当我从某个地方复制示例时,我也将其包含在StackOverflow问题中。这里哪种方法合适?谢谢。