我有一个函数,传递的参数是 5 个文件路径。但是,第一个路径是 csv.gz,其中文件内部似乎存在未定义的字符。我该如何解决这个问题?
我使用的是Python 3.11.1版本。代码和错误消息如下所示。
function(r"filepath1", r"filepath2", r"filepath3", r"filepath4", r"filepath5")
错误信息:
Cell In[3], line 8, in function(filepath1, filepath2, filepath3, filepath4, filepath5)
6 file1DateMap = {}
7 infd = open(file1path1, 'r')
8 infd.readline()
9 for line in infd:
10 tokens = line.strip().split(',')
File ~\AppData\Local\Programs\Python\Python311\Lib\encodings\cp1252.py:23, in IncrementalDecoder.decode(self, input, final)
22 def decode(self, input, final=False):
23 return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 94: character maps to undefined
我试过了
file = open(filename, encoding="utf8")
但是在我的 Python 版本中编码未定义。
我尝试了“打开”方法
file2 = r"file2path"
file3 = r"file3path"
file4 = r"file4path"
file5 = r"file5path"
file1name = r"file1path"
with open(file1name, 'r') as file1:
function(file1, file2, file3, file4, file5)
但该函数需要一个字符串:
TypeError:需要 str、bytes 或 os.PathLike 对象,而不是 TextIOWrapper
我期待该函数运行并将处理后的输出写入桌面上的文件夹。
更新
我在 Visual Studio Code 中检查了文件的编码,它显示为 UTF 8。我编写了以下代码:
with open(r"path1", encoding="utf8") as openfile1:
file1 = openfile1.read()
收到此错误:
UnicodeDecodeError:“utf-8”编解码器无法解码位置 1 中的字节 0x8b:起始字节无效
更新2
用此代码检查编码
with open(r"filepath1") as f:
print(f)
编码='cp1252'
但是现在当我传递新的编码参数时:
with open(r"path1", encoding="cp1252") as openfile1:
file1 = openfile1.read()
我回到方 1,并出现以下错误消息:
UnicodeDecodeError:“charmap”编解码器无法解码位置 94 中的字节 0x9d:字符映射到未定义
更新3
Gzip 确实有效。我使用了以下代码:
import gzip
with gzip.open(r"path1", mode="rb") as openfile1:
file1 = openfile1.read()
我还能够读取文件的前 10 行。然而,当我将它传递回函数时,它现在给我这个错误:
FileNotFoundError:[Errno 2]没有这样的文件或目录
然后打印文件中的所有字段。这与压缩选项有关吗?
更新4
我检查了当前的wd和绝对文件路径:
cwd = os.getcwd()
cwd
输出:venvpath
dir_path = os.path.dirname(os.path.realpath(file1))
dir_path
收到此错误消息:
文件:700,在实际路径中(路径,严格)
ValueError:_getfinalpathname:Windows 路径太长
不确定这是否会导致无法将文件传递到函数中。
此源代码中存在一些令人困惑的地方。
with open(file1name, 'r') as file1:
function(file1, file2, file3, file4, file5)
请理解
file1
是一个打开的文件句柄,
带有 TextIOWrapper 的 type(...)
。
它是可迭代的,您可以从中请求文本行。
相比之下,file2
等人。是 str
路径名;
您无法从这些对象请求文件系统文本行。
您为它们选择的并行命名结构 可能会让自己感到困惑加上任何不幸的维护 在未来几个月内遇到此代码的工程师。 建议您采用类似
path2
.. path5
. 的名字
您的默认编码似乎是 代码页1252。 您请求使用
open(file1name, 'r')
进行编码
省略可选的 encoding=
参数。
请注意,mode='r'
是默认值,
所以你也可以把那个排除在外。
相比之下,
open(filename, encoding="utf8")
使用完全不同的编码打开读取访问。
编码是底层 .CSV 文件的属性, 而不是你的程序。 也就是说,您必须知道正确的底层编码是什么, 并且您必须告诉
open
正确的编码。
您可以默认执行此操作,也可以明确执行此操作,
只要你做对了。
我建议明确地这样做。
如果您不知道编码, 使用
/usr/bin/file
、/usr/local/bin/iconv
、
或文本编辑器来了解它是什么,
也许将其更改为 UTF-8
如果您对其当前的编码不满意。
大多数现代机器上的大多数文件 应该是 UTF-8 编码——否则的话 就是自找麻烦。但我离题了。
一旦您选择了一些已知的编码, 通过
open
将其传递给 encoding=
参数,您就可以开始营业了!
如果您有一个压缩为 gzip 文件的 CSV 文件,您应该能够像以下那样简单地读取 gzip 文件:
with gzip.open("input.csv.gz", "rt", newline="", encoding="utf-8") as f:
我相信您会希望
rt
将其读取为文本(而不是 rb
它将返回未解码的字节);当然,选择文件的实际编码(我的示例始终使用 utf-8)。
要进一步解码文本文件中的 CSV
f
,我建议使用标准库的 csv 模块:
...
reader = csv.reader(f)
for row in reader:
print(row)