NameError: o nome global 'unicode' não está definido - no Python 3

136

Estou tentando usar um pacote Python chamado bidi. Em um módulo neste pacote (algoritm.py), existem algumas linhas que me dão erro, embora faça parte do pacote.

Aqui estão as linhas:

# utf-8 ? we need unicode
if isinstance(unicode_or_str, unicode):
    text = unicode_or_str
    decoded = False
else:
    text = unicode_or_str.decode(encoding)
    decoded = True

e aqui está a mensagem de erro:

Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    bidi_text = get_display(reshaped_text)
  File "C:\Python33\lib\site-packages\python_bidi-0.3.4-py3.3.egg\bidi\algorithm.py",   line 602, in get_display
    if isinstance(unicode_or_str, unicode):
NameError: global name 'unicode' is not defined

Como devo reescrever essa parte do código para que funcione no Python3? Além disso, se alguém tiver usado o pacote bidi com o Python 3, informe-me se eles encontraram problemas semelhantes ou não. Eu aprecio sua ajuda.

TJ1
fonte

Respostas:

214

O Python 3 renomeou o unicodetipo para str, o strtipo antigo foi substituído por bytes.

if isinstance(unicode_or_str, str):
    text = unicode_or_str
    decoded = False
else:
    text = unicode_or_str.decode(encoding)
    decoded = True

Você pode ler o HOWTO de portabilidade do Python 3 para obter mais detalhes. Há também o Porting to Python 3: Um guia detalhado da Lennart Regebro , online gratuitamente.

Por último, mas não menos importante, você pode apenas tentar usar a 2to3ferramenta para ver como isso traduz o código para você.

Martijn Pieters
fonte
Então, devo escrever: if isinstance (unicode_or_str, str)? Que tal 'unicode_or_str'?
TJ1 9/11
1
O nome da variável não importa muito aqui; if isinstance(unicode_or_str, str)deve funcionar. Renomear o nome da variável é opcional.
Martijn Pieters
5
@ TJ1: Certifique-se de não remover um parêntese de fechamento ou algo em algum lugar. O código deve funcionar bem com apenas unicode substituído por str.
Martijn Pieters
você está certo Martijn, esqueci de incluir: no meu código, obrigado pela ajuda, ele funciona agora.
TJ1 9/11
Eu gosto da ferramenta 2to3
ji-ruh 25/10
22

Se você precisar que o script continue trabalhando em python2 e 3 como eu, isso pode ajudar alguém

import sys
if sys.version_info[0] >= 3:
    unicode = str

e pode fazer apenas por exemplo

foo = unicode.lower(foo)
Neil McGill
fonte
1
Esta é a ideia certa, boa resposta. Apenas para adicionar um detalhe, se você estiver usando a sixbiblioteca para gerenciar a compatibilidade do Python 2/3, poderá fazer o seguinte: em if six.PY3: unicode = strvez de sys.version_infooutras coisas. Isso também é muito útil para evitar que erros de linter relacionados ao unicode sejam indefinidos no Python 3, sem a necessidade de isenções especiais de regras de linter.
ely
20

Você pode usar a biblioteca seis para dar suporte ao Python 2 e 3:

import six
if isinstance(value, six.string_types):
    handle_string(value)
atm
fonte
1

Espero que você esteja usando Python 3, Str são unicode por padrão, então substitua a Unicodefunção pela Strfunção String .

if isinstance(unicode_or_str, str):    ##Replaces with str
    text = unicode_or_str
    decoded = False
MJ
fonte
2
que não preserva o BC como a resposta de @atm Considere retirar ou atualizar sua resposta. Não há nenhuma razão para deixar os usuários python2 trás ou ter quebrar python3
MrMesees