Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.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
Python2和3 csv阅读器_Python_Encoding_Csv_Python 3.x - Fatal编程技术网

Python2和3 csv阅读器

Python2和3 csv阅读器,python,encoding,csv,python-3.x,Python,Encoding,Csv,Python 3.x,我试图使用csv模块读取utf-8CSV文件,但由于编码原因,我在为Python2和Python3创建通用代码时遇到了一些麻烦 以下是Python 2.7中的原始代码: with open(filename, 'rb') as csvfile: csv_reader = csv.reader(csvfile, quotechar='\"') langs = next(csv_reader)[1:] for row in csv_reader: pass

我试图使用csv模块读取utf-8CSV文件,但由于编码原因,我在为Python2和Python3创建通用代码时遇到了一些麻烦

以下是Python 2.7中的原始代码:

with open(filename, 'rb') as csvfile:
    csv_reader = csv.reader(csvfile, quotechar='\"')
    langs = next(csv_reader)[1:]
    for row in csv_reader:
        pass
但是当我用Python3运行它时,它不喜欢我打开文件时没有“编码”。我试过这个:

with codecs.open(filename, 'r', encoding='utf-8') as csvfile:
    csv_reader = csv.reader(csvfile, quotechar='\"')
    langs = next(csv_reader)[1:]
    for row in csv_reader:
        pass

现在python 2无法解码“for”循环中的行。所以我应该怎么做呢?

事实上,在Python 2中,文件应该以二进制模式打开,而在Python 3中,文件应该以文本模式打开。(你忘了)

您必须在if块中打开文件

import sys

if sys.version_info[0] < 3: 
    infile = open(filename, 'rb')
else:
    infile = open(filename, 'r', newline='', encoding='utf8')


with infile as csvfile:
    ...
导入系统 如果系统版本信息[0]<3: infle=open(文件名为'rb') 其他: infle=open(文件名为'r',换行符为''',编码为'utf8') 使用内嵌作为csvfile: ...
我知道一个老问题,但我正在考虑如何做到这一点。以防万一有人过来,可能会发现它很有用

这就是我解决问题的方法,谢谢Lennart Regebro的提示:

if sys.version > '3':
       rd = csv.reader(open(input_file, 'r', newline='',
       encoding='iso8859-1'), delimiter=';', quotechar='"')
else:
       rd = csv.reader(open(input_file, 'rb'), delimiter=';',
       quotechar='"')
然后做你需要做的事情:

for row in rd:
       ......

更新:当我的原始答案中的代码起作用时,我同时发布了一个小软件包,它为Python 2提供了一个类似Python 3的接口。因此,独立于Python版本,您只需执行

import csv342 as csv
import io
with io.open('some.csv', 'r', encoding='utf-8', newline='') as csv_file:
    for row in csv.reader(csv_file, delimiter='|'):
        print(row)
原始答案:这里有一个解决方案,即使使用Python2,也可以将文本解码为Unicode字符串,从而使用UTF-8以外的编码

下面的代码定义了一个函数
csv\u rows()
,该函数将文件内容作为列表序列返回。用法示例:

对于csv_行中的行('some.csv',encoding='iso-8859-15',delimiter='|'):
打印(行)
以下是csv_rows()的两个变体:一个用于Python3+,另一个用于Python2.6+。在运行时,它会自动选择合适的变量
UTF8Recoder
UnicodeReader
是的逐字副本

导入csv
输入io
导入系统
如果系统版本信息[0]>=3:
#Python3变体。
def csv_行(csv_路径、编码,**关键字):
将io.open(csv_路径'r',换行符='',编码=编码)作为csv_文件:
对于csv.reader(csv_文件,**关键字)中的行:
产量行
其他:
#Python2变体。
导入编解码器
UTF8类记录器:
"""
迭代器,读取编码流并将输入重新编码到UTF-8
"""
定义初始化(self,f,encoding):
self.reader=codecs.getreader(编码)(f)
定义(自我):
回归自我
def next(自我):
返回self.reader.next().encode(“utf-8”)
类UnicodeReader:
"""
一个CSV阅读器,它将在CSV文件“f”中的行上进行迭代,
以给定的编码方式进行编码。
"""
def _uinit _;(self,f,方言=csv.excel,encoding=“utf-8”,**kwds):
f=UTF8Recoder(f,编码)
self.reader=csv.reader(f,方言=方言,**kwds)
def next(自我):
row=self.reader.next()
返回[unicode(s,“utf-8”)表示第行中的s]
定义(自我):
回归自我
def csv_行(csv_路径,编码,**kwds):
使用io.open(csv_路径,'rb')作为csv_文件:
对于UnicodeReader中的行(csv_文件,encoding=encoding,**kwds):
产量行

那么您想要在Python 2.7和3上运行不变的代码吗?可能不可能,因为字符串处理等发生了如此多的变化。是否可以为python 2或3指定块代码?您可以检查
sys.version
,并在代码周围包装一个
if-else
语句,是的。@Tim pietzhker;请求原谅比请求允许要好。我想你在错误的示例中使用了b标志,我把它换了过来。你能用文件句柄上的做
吗?@Tim:这不是文件句柄,它是文件对象,你可以用文件对象上的
。这正是你使用open(…
)进行
操作时所做的。这是有道理的。你从来没有这样看过,文档中总是使用open(…)
进行
,但这种方式还不错-使你能够包装
open()
中尝试
阻塞并捕获未找到的
文件
等,然后用
块将其交给
。或者,在某些情况下,
如果sys.version<'3':open=codecs。open
@agf:是的,这也可以工作。codecs.open和Python 3 open并不完全相同,尽管存在微妙的陷阱,但通常也可以工作.在2.6和2.7中,您可以从io导入打开执行