读取 utf-8 编码文件时,Path.read_text(pathlib)出现意外结果

问题描述 投票:0回答:1

今天我了解到,对于

open(filename).read()
,我们不能指望绑定到隐藏文件对象的资源会立即返回,尽管我在我的系统上观察到了这一点。 (请参阅问题的已接受的答案读取整个文件是否会使文件句柄保持打开状态?)。

第二个答案让我拒绝推出自己的辅助函数,它告诉我

pathlib
已经提供了这个功能。

但实际上,情况似乎并非如此。使用以下脚本(

test.py
),我得到不同的结果:

# The German accent characters are Ä,Ö,Ü,ä,ö,ü, and ß.
from pathlib import Path;

def pathlib_read_text(filename, encoding=None):
    return Path(filename, encoding=encoding).read_text()

def mylocal_read_text(filename, encoding=None):
    with open(filename, encoding=encoding) as f:
        return f.read()

def test(fun):
    print(fun+'_read_text:')
    print(eval(fun+'_read_text')(__file__, 'utf-8'))

test('pathlib')
test('mylocal')

Windows 控制台的输出 (

python test.py
) 在第一个块中包含
Ã",Ã-,Ão,ä,ö,ü, and ÃY.
,当我将输出重定向到文件中时,我得到第二个块错误(在 Notepad++ 中,它以黑底白字显示
xC4,xD6,xDC,xE4,xF6,FC, and xDF
)如果该文件被视为 utf-8。

有什么是我忽略的吗?

我尝试检查3.6.3代码,但到目前为止没有发现错误......

编辑

以下版本强化了我的感觉,即这是

pathlib
或底层库/函数之一中的错误。也许这只是一个 Windows 问题,默认编码与
utf-8
大部分不同。现在在控制台窗口中运行测试就足够了。

accents = '''
Ä,Ö,Ü,ä,ö,ü,ß
'''
from pathlib import Path;
import codecs

def pathlib_read_text(filename, encoding=None, errors=None):
    return Path(filename, encoding=encoding, errors=errors).read_text()

def mylocal_read_text(filename, encoding=None, errors=None):
    with open(filename, encoding=encoding, errors=errors) as f:
        return f.read()

def space_it(error):
    return ' ';
codecs.register_error('space_it', space_it)

def test(fun):
    s = eval(fun+'_read_text')(__file__, 'utf-8', errors='space_it')
    print(fun+'_read_text:', s.split("\n")[1] == accents.strip())

test('pathlib')
test('mylocal')

它产生以下输出:

pathlib_read_text: False
mylocal_read_text: True
python file-io encoding pathlib
1个回答
0
投票

我的实际问题显然是复制粘贴错误:传递给

Path
构造函数的关键字参数应该传递给
read_text()
方法。

在审查这个问题时,Python 3.12.3 发出的警告迫使我现在解决这个问题:

DeprecationWarning:支持向 pathlib 提供关键字参数。PurePath 已弃用,并计划在 Python 3.14 中删除

修复已应用于以下代码(请参阅

HERE
评论):

accents = '''
Ä,Ö,Ü,ä,ö,ü,ß
'''
from pathlib import Path;
import codecs

def pathlib_read_text(filename, encoding=None, errors=None):
    return Path(filename).read_text(encoding=encoding, errors=errors) # <-- HERE

def mylocal_read_text(filename, encoding=None, errors=None):
    with open(filename, encoding=encoding, errors=errors) as f:
        return f.read()

def space_it(error):
    return ' ';
codecs.register_error('space_it', space_it)

def test(fun):
    s = eval(fun+'_read_text')(__file__, 'utf-8', errors='space_it')
    print(fun+'_read_text:', s.split("\n")[1] == accents.strip())

test('pathlib')
test('mylocal')

现在我们在输出中得到了预期的结果:

pathlib_read_text: True
mylocal_read_text: True
© www.soinside.com 2019 - 2024. All rights reserved.