Python 文件名/路径解析错误的希伯来语编码(使用 optparse 库)

标签 python linux unicode filesystems hebrew

这段代码有问题:

import optparse
parser = optparse.OptionParser(version=__version__,
    usage="%prog [options] file1 ... host[:dest]",
    description=main.__doc__)
parser.add_option("-c", "--config", help="Specify an alternate config "
    "file.  Default = '%s'" % config_file)
parser.add_option('-l', '--log-level', type="choice",
    choices=LOG_LEVELS.keys(),
    help="Override the default logging level. Choices=%s, Default=%s" %
        (",".join(LOG_LEVELS.keys()), LOG_LEVEL))
parser.add_option("-o", "--overwrite", action="store_true",
    help="If specified, overwrite existing files at destination.  If "
    "not specified, throw an exception if you try to overwrite a file")
parser.add_option('-s', "--speed", action="store_true", \
    help="If specifed, print the data transfer rate for each file "
        "that is uploaded (infers verbose option)")
parser.add_option('-v', '--verbose', action="store_true",
    help="If specified, print every file that is being uploaded and every "
        "directory that is being created")
parser.add_option("-u", "--user", help="The username to use for "
    "authentication.  Not needed if you have set up a config file.")
parser.add_option("-p", "--password", help="The password to use for "
    "authentication.  Not needed if you have set up a config file.")

parser.set_defaults(config=config_file, log_level=LOG_LEVEL)
options, args = parser.parse_args()
print (args)

如您所见,当我打印我们正在使用希伯来语命名文件进行的测试的参数时,打印结果包括:['/root/mezeo_sdk/1/\xfa\xe5\xeb\xf0\xe9\xfa\xf2\xe1\xe5\xe3\xe4.xlsx', '主机名'] 而不是/root/mezeo_sdk/1/"תוכנית עבודה.xlsx"

此外,脚本将文件上传到服务器后的最终结果(文件名的传递方式)是:http://i.imgur.com/pP6fA.png

文件名本身在 linux 源上很好,因为如果我将它 SCP 到我自己的计算机上它看起来不错,但一旦我使用 python 脚本将它传输到文件服务器后就不行了。

我也不认为问题出在文件服务器端,因为如果我使用网络界面上传希伯来文命名的文件,它们就可以了。

我认为问题在于 optparse 库的使用。

最佳答案

一如既往,我将从 Unicode 建议阅读开始:您真的应该阅读其中一个或两个

简而言之,Unicode 代码点是代表一个字符1 的抽象“东西”。程序员喜欢使用这些,因为我们喜欢将字符串视为一次一个字符。不幸的是,很久以前就规定一个字符必须适合一个字节的内存,因此最多可以有 256 个不同的字符。这对简单的英语很好,但对其他任何东西都不起作用。有一个全局代码点列表——数以千计——旨在包含每个可能的字符,但显然它们不适合一个字节。

解决方案:构成字符串的代码点的有序列表与其作为字节序列的编码之间存在差异。每当你使用一个字符串时,你必须清楚它应该是这些形式中的哪一种。要在形式之间转换,你可以 .encode() 代码点列表(Unicode 字符串)作为字节列表,并将 .decode() 字节转换为代码点列表。为此,您需要知道如何将代码点映射到字节,反之亦然,这就是编码。

1有点。


好吧,现在已经不碍事了,让我们看看你有什么。您已经给出了一个(原始)字符串——一个字节序列:

\xfa\xe5\xeb\xf0\xe9\xfa \xf2\xe1\xe5\xe3\xe4

你想成为的编码

תוכנית עבודה

一点谷歌搜索告诉我你正在使用 Windows-1255编码,它是 ASCII 的扩展,使用高字节来保存希伯来字母。您希望使用 Unicode 格式的字符串,因为 Unicode 表示普通数据。因此,您应该使用编码"Windows-1255"解码字节序列:

>>> s
'\xfa\xe5\xeb\xf0\xe9\xfa \xf2\xe1\xe5\xe3\xe4'
>>> s.decode("Windows-1255")
u'\u05ea\u05d5\u05db\u05e0\u05d9\u05ea \u05e2\u05d1\u05d5\u05d3\u05d4'

现在您拥有正确分类的数据。接下来,您需要将数据发送到服务器,这意味着将其编码为正常编码,即“UTF-8”:

>>> s.decode("Windows-1255").encode("utf-8")
'\xd7\xaa\xd7\x95\xd7\x9b\xd7\xa0\xd7\x99\xd7\xaa \xd7\xa2\xd7\x91\xd7\x95\xd7\x93\xd7\x94'

最后,你可能想知道服务器哪里出了问题。好吧,如果您不指定数据编码,人们将不得不猜测,这是一个注定要失败的企业。在您的情况下,您似乎将原始字节发送到服务器,然后服务器将它们解码为 latin-1。这给出了您看到的奇怪的重音字母,因为 latin-1 使用 ASCII 字节的上半部分,而不是希伯来语字符,而是用于重音英语字符。

故事的寓意:理解 Unicode!

关于Python 文件名/路径解析错误的希伯来语编码(使用 optparse 库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10223322/

相关文章:

python - Unicode 字典键问题

python - TensorFlow Python 脚本被杀死

python - 如何从 tkinter 中的特定网格位置检索值?

Python 套接字 GetAddrInfo (GAI) 错误

linux - 为什么有些应用程序附带共享库?

linux - centOS7 netinstall with kickstart 获取安装源失败

python - 将 2 个列表汇总到另一个列表中

linux - 导出变量,这些变量是 shell 中的变量值

python - 通过 URL 发送列表

php - 如何将 Unicode 转义序列转换为 PHP 中的文本?