Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 非ASCII的比较仅在空闲时有效_Python_Windows_Python 2.7_Character Encoding - Fatal编程技术网

Python 非ASCII的比较仅在空闲时有效

Python 非ASCII的比较仅在空闲时有效,python,windows,python-2.7,character-encoding,Python,Windows,Python 2.7,Character Encoding,我正在做一个相当简单的代码,将欧洲葡萄牙语输入转换成巴西葡萄牙语——因此有很多重音字符,如á、é、À、ç等 基本上,目标是从列表中查找文本中的单词,并用第二个列表中的BR单词替换它们 代码如下: #-*- coding: latin-1 -*- listapt=["gestão","utilizador","telemóvel"] listabr=["gerenciamento", "usuário", "celular"] while True: #this is all bec

我正在做一个相当简单的代码,将欧洲葡萄牙语输入转换成巴西葡萄牙语——因此有很多重音字符,如á、é、À、ç等

基本上,目标是从列表中查找文本中的单词,并用第二个列表中的BR单词替换它们

代码如下:

#-*- coding: latin-1 -*-

listapt=["gestão","utilizador","telemóvel"]
listabr=["gerenciamento", "usuário", "celular"]

while True:

    #this is all because I need to be able to input multiple lines of text, seems to be working fine 

    print ("Insert text")
    lines = []

    while True:
        line = raw_input()
        if line != "FIM":
            lines.append(line)
        else:
            break
    text = '\n'.join(lines)    

    for word in listapt:
        if word in text:
            num = listapt.index(word)
            wordbr = listabr[num]
            print(word + " --> " + wordbr) #just to show what changes were made
            text = text.replace(word, wordbr)

    print(text)
我在Windows上使用IDLE运行代码,并双击
.py
文件。
使用IDLE时代码工作正常,但双击
.py
文件时不匹配和替换字符。

首先尝试执行以下代码,它应该可以解决问题:

# -*- coding: latin-1 -*-

listapt=[u"gestão",u"utilizador",u"telemóvel"]
listabr=[u"gerenciamento",u"usuário", u"celular"]

lines=[]
line = raw_input()
line = line.decode('latin-1')
if line != "FIM":
    lines.append(line)

text = u'\n'.join(lines)    

for word in listapt:
    if word in text:
        print("Hello")
        num = listapt.index(word)
        print(num)
        wordbr = listabr[num]
        print(wordbr) 

我看不出这里有什么问题

根据您对原始输入的使用情况,您似乎正在使用Python2.x

这可能是因为我正在从堆栈溢出中复制粘贴,并且您有一个不同的开发环境

尝试在最新的Python 3解释器下运行脚本,并删除“#-*-编码:”行

这应该可以在代码中更快地解决UnicodeDecodeError问题,或者工作正常

这里的问题是Python2.x在尝试在字节序列(Python2.x字符串所包含的内容,例如二进制文件内容)和人类有意义的文本(unicode,例如用于用户信息显示汉字)之间进行转换时,在某些时候会感到困惑,因为它对人类可读文本如何编码到Python字符串中的字节序列做出了错误的假设


这是Python 3试图更好地/不太含糊地解决的一个细节。

以下是代码在IDLE中按预期工作的原因,而不是通过CMD或双击:

  • 您的代码是UTF-8编码的,而不是拉丁语-1编码的
  • IDLE始终在UTF-8“输入/输出”模式下工作
  • 在Windows上,CMD/双击将使用非UTF-8 8位区域设置
  • 当代码将输入与硬编码字符串进行比较时,它是在字节级别进行比较的。空闲时,它将UTF-8与硬编码UTF-8进行比较。在CMD上,它将非UTF-8 8bit与硬编码UTF-8进行比较(如果您使用的是股票MacOS,它也可以工作)
  • 解决这个问题的方法是确保你正在比较“苹果与苹果”。您可以通过将所有内容转换为相同的编码来实现这一点。例如,将读取的输入转换为UTF-8,使其与硬编码字符串匹配。更好的解决方案是将所有[字节]字符串转换为Unicode字符串(不带编码的字符串)。如果您使用的是Python3,这将是全自动的

    在Python2.x上,您需要做三件事:

  • 在所有源代码字符串前面加上
    u
    ,使其成为Unicode字符串:

    listapt=[u"gestão",u"utilizador",u"telemóvel"]
    listabr=[u"gerenciamento",u"usuário", u"celula]
    ...
    if line != u"FIM":
    
    或者,添加来自未来导入unicode文本的
    ,以避免更改所有代码

  • 使用正确的编码头对文件进行编码。我怀疑您的标题应该是
    utf-8
    。例如

    #-*- coding: utf-8 -*-
    
  • 原始输入的结果
    转换为Unicode。这必须通过检测到的标准输入编码来完成:

    import sys
    line = raw_input().decode(sys.stdin.encoding) 
    
  • 顺便说一下,更好的方法是对单词列表进行建模以替换它,使用dict。键是原始单词,值是替换。例如

    words = { u"telemóvel": u"celula"}
    

    如果在某处添加基本的
    打印“gestão”
    ,是否会收到相同的错误消息?不,我没有。这似乎很好。我用一个新问题编辑了这个问题——它在空闲时工作,但在我直接运行或转换为exe时不工作。为什么?你说的“转换为exe”是什么意思?我使用py2exe创建了一个可执行文件,只是为了测试它,因为这可能是最终目标。不要硬编码
    解码
    -这假设终端使用的是
    拉丁语-1
    。当OP双击或从CMD运行时,这可能适用于OP。我试过了,实际上我可以在空闲状态下运行它,但是如果我双击文件或从cmd打开它,它就不起作用了。这的最终目标可能是创建一个可共享的可执行文件,因此从空闲运行是不够的。为什么会这样?天哪,是的!成功了!非常感谢。关于你的最后一个提示,这是一个非常好的提示,谢谢!请注意,Windows控制台是UTF-16,但默认情况下,Python 2从控制台读取最佳匹配(非严格)字节字符串。这使用控制台的当前输入代码页,默认为系统区域设置的OEM代码页(例如西欧的850)。您将阅读此代码页中未定义的所有字符的mojibake胡说八道(例如,“αβγδε”->“aßde”)。唯一可靠的解决方案是使用控制台的Unicode API(例如,
    ReadConsoleW
    ),就像Python 3.6+一样。在Python2中,您可以安装并启用win_unicode_控制台包。在这个答案中没有理由提到CMD,因为OP通过双击文件来运行脚本。将CMD引入讨论会导致混淆控制台和CMD是同一件事。cmd.exe和python.exe都是控制台应用程序,它们继承或分配由系统实现的控制台窗口(在Windows 7+中由conhost.exe实现,但这是一个实现细节)。