在不事先知道代码页的情况下将原始字节字符串转换为Unicode

时间:2013-05-09 19:11:24

标签: python windows unicode rawbytestring

使用右键单击菜单上下文时,Windows将文件路径作为原始(字节)字符串类型传递。

例如:

path = 'C:\\MyDir\\\x99\x8c\x85\x8d.mp3'

我的应用程序中的许多外部程序包都需要unicode类型字符串,因此我必须将其转换为unicode

如果我们事先知道原始字符串的编码(在示例中,它是cp1255),那将很容易。但是我不知道世界上每台计算机本地使用哪种编码。

如何将string转换为unicode?也许需要使用win32api

2 个答案:

答案 0 :(得分:3)

不知道为什么你可能会获得DOS代码页(862)而不是ANSI(1255) - 如何设置右键单击选项?

无论哪种方式 - 如果您需要在参数中接受任意Unicode字符,则无法从Python 2 sys.argv中执行此操作。此列表是从非Unicode版本的Win32 API(GetCommandLineA)返回的字节填充的,并且该编码从不是Unicode安全的。

包括Java和Ruby在内的许多其他语言都在同一条船上;限制来自Microsoft C运行时的C标准库函数的实现。要修复它,可以在Windows上调用Unicode版本(GetCommandLineW),而不是依赖于跨平台标准库。 Python 3就是这样做的。

在Python 2的同时,您可以通过自己调用GetCommandLineW来实现,但这并不是特别漂亮。如果需要Windows样式的参数splittng,也可以使用CommandLineToArgvW。您可以使用win32扩展名执行此操作,也可以只使用ctypes

Example(尽管最好跳过将Unicode字符串编码回UTF-8字节的步骤。)

答案 1 :(得分:2)

通常我使用自己的util函数从通常的代码页到unicode的安全转换。对于读取默认操作系统编码, locale.getpreferredencoding 函数可能有帮助(http://docs.python.org/2/library/locale.html#locale.getpreferredencoding)。

通过迭代某些预定义编码尝试转换为unicode的util函数示例:

# coding: utf-8
def to_unicode(s):
    if isinstance(s, unicode): return s

    from locale import getpreferredencoding
    for cp in (getpreferredencoding(), "cp1255", "cp1250"):
        try:
            return unicode(s, cp)
        except UnicodeDecodeError:
            pass
    raise Exception("Conversion to unicode failed")
    # or fallback like:
    # return unicode(s, getpreferredencoding(), "replace")

print (to_unicode("addđšđč枎ŠĐ"))

可以使用unicode函数参数errors =“replace”启用后备。参考http://docs.python.org/2/library/functions.html#unicode

要转换回某些代码页,您可以查看this