6

我已经阅读了UnicodeDecodeError: 'charmap' codec can't decode byte X in position Y: character maps to <undefined>。虽然错误消息相似,但代码完全不同,因为我os.popen在这个问题中使用,而不是open. 我不能使用其他问题的答案来解决这个问题。

output = os.popen("dir").read()

该行应该将命令“dir”的输出分配给变量“output”,导致此错误:

'charmap' codec can't decode byte 0x88 in position 260: character maps to <undefined>

我认为这可能会发生,因为文件夹中的某些文件的名称中包含ł、ą、ęć等字母。我不知道如何解决这个问题。

4

3 回答 3

6

os.popen只是一个包装器subprocess.Popen和一个io.TextIOWrapper对象:

返回的文件对象读取或写入文本字符串而不是字节。

如果 Python 的默认编码不适合你,你应该subprocess.Popen直接使用。

根本问题是 cmd 默认情况下会写入 ansi 垃圾,即使输出到管道也是如此。此行为可能取决于您的 Windows 版本。

您可以通过将/U标志传递给 cmd 来解决此问题:

p = subprocess.Popen('cmd /u /c dir', stdout=subprocess.PIPE)
result = p.communicate()
text = result[0].decode('u16')
于 2017-02-04T14:28:23.870 回答
3

在这种情况下,使用subprocess.Popen太笼统,太冗长,太难记了。改为使用subprocess.check_output

它返回一个bytes对象,该对象可以strdecode函数转换为。

import subprocess
x = subprocess.check_output(['ls','/'])
print(x.decode('utf-8'))

在线尝试!

于 2018-08-09T11:51:50.433 回答
0

如果有人像我一样在python2中使用with -statement 和 readline() 的组合(对于 Windows 中的时区 Util),它将不适用于 python3:

with os.popen("tzutil /l") as source:
    key, value = self.get_key_value(source, True)
    while value and key:
        timezones_to_json.append({u"key": key, u"value": value, u"toolTip": key})
        key, value = self,get_key_value(source, False)
return timezones_to_json

def get_key_value(self, source, first=False):
    if not first:
        source.readline()
    value = source.stdout.readline().strip()
    key = source.stdout.readline().strip()
    return key, value

所以我对python3的更改是:

  1. 就像@Josh Lee 说我使用了 subprocess.Popen 一样,但我有一个AttributeError: __exit__

  2. 所以你必须.stdout在最后插入,所以 with 语句中的对象有__enter____exit__方法:

    with subprocess.Popen(['tzutil', '/l'], stdout=subprocess.PIPE).stdout as source:
    
于 2019-11-14T10:34:31.603 回答