Sac*_*chu 2 python csv python-3.x
我在 Python 3.6.4 中编写了以下代码来读取目录中的 .csv 文件“Data.csv”并将内容复制到 NamedTemporaryFile“temp_file”
file_path= "Data.csv"
temp_file=NamedTemporaryFile(delete=False)
with open(file_path,"rb") as csvfile,temp_file:
fieldnames=["id","Title","Desc","Comments"]
reader=csv.DictReader(csvfile,fieldnames=fieldnames)
writer=csv.DictWriter(temp_file,fieldnames=fieldnames)
for row in reader:
temp_row={"id":row["id"],"Title":row["Title"],"Desc":row["Desc"],"Comments":row["Comments"],}
writer.writerow(temp_row)
print(row)
Run Code Online (Sandbox Code Playgroud)
执行上面的代码在迭代器行中出现错误(对于阅读器中的行):错误说:
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
Run Code Online (Sandbox Code Playgroud)
我寻找解决方案并找到了这个答案
但这并没有解决我的问题,因为当我将“rb”更改为“rt”时,我开始收到另一个错误
writer.writerow(temp_row)
Run Code Online (Sandbox Code Playgroud)
这个错误说:
TypeError: a bytes-like object is required, not 'str'
Run Code Online (Sandbox Code Playgroud)
我认为这个问题只出现在Python 3中,不影响Python 2
我已经尝试过诸如将字符串转换为字节的函数之类的方法encode()以及decode()一些库函数,例如json.dumps().
您以二进制模式打开文件:
with open(file_path,"rb") as csvfile,temp_file:
# ^^ b is for binary
Run Code Online (Sandbox Code Playgroud)
不要那样做。错误消息告诉您不应该这样做,它特别提醒您以文本模式打开文件:
(did you open the file in text mode?)
Run Code Online (Sandbox Code Playgroud)
b从文件模式中删除。
该类还默认为二进制模式,您需要告诉它以文本NamedTemporaryFile()模式'w+b'打开文件;使用'w+'或'w'。
更正的代码:
temp_file = NamedTemporaryFile(mode='w+', delete=False)
with open(file_path, "r") as csvfile, temp_file:
Run Code Online (Sandbox Code Playgroud)
在Python 2中,该csv模块只能以二进制模式处理数据,部分原因是Python在首次创建该模块时没有强大的Unicode支持,并且因为在Python 2中,某些平台上的文本模式文件以与CSV 标准。
在 Python 3 中,强烈建议newline=''您在打开文件时添加以下内容来关闭行结束翻译:
temp_file = NamedTemporaryFile(mode='w+', newline='', delete=False)
with open(file_path, "r", newline='') as csvfile, temp_file:
Run Code Online (Sandbox Code Playgroud)
我还强烈考虑显式设置编码,而不是依赖系统默认值。
附带说明一下,在复制字典时无需拼写出所有列名称,甚至不必为每一行创建一个新字典,因为DictReader()和DictWriter fieldnames列表匹配。您可以将 reader 直接传递给该DictWriter.writerows()方法:
file_path = "Data.csv"
fieldnames = ["id", "Title", "Desc", "Comments"]
temp_file = NamedTemporaryFile(mode='w+', newline='', delete=False)
with open(file_path, "r", newline='') as csvfile, temp_file:
reader = csv.DictReader(csvfile, fieldnames=fieldnames)
writer = csv.DictWriter(temp_file, fieldnames=fieldnames)
writer.writerows(reader)
Run Code Online (Sandbox Code Playgroud)
此时我确实想知道您是否只想使用shutil.copyfileob()并避免解析为字典,然后序列化回 CSV。