Удаление символов не-ascii из любого заданного типа string в Python

>>> teststring = 'aõ'
>>> type(teststring)
<type 'str'>
>>> teststring
'a\xf5'
>>> print teststring
aõ
>>> teststring.decode("ascii", "ignore")
u'a'
>>> teststring.decode("ascii", "ignore").encode("ascii")
'a'

что я действительно хотел, чтобы он хранил внутренне, поскольку я удаляю символы, отличные от ascii. Почему декодирование ("ascii выдают строку юникода?

>>> teststringUni = u'aõ'
>>> type(teststringUni)
<type 'unicode'>
>>> print teststringUni
aõ
>>> teststringUni.decode("ascii" , "ignore")

Traceback (most recent call last):
  File "<pyshell#79>", line 1, in <module>
    teststringUni.decode("ascii" , "ignore")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf5' in position 1: ordinal not in range(128)
>>> teststringUni.decode("utf-8" , "ignore")

Traceback (most recent call last):
  File "<pyshell#81>", line 1, in <module>
    teststringUni.decode("utf-8" , "ignore")
  File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf5' in position 1: ordinal not in range(128)
>>> teststringUni.encode("ascii" , "ignore")
'a'

Это снова то, что я хотел. Я не понимаю этого поведения. Может кто-нибудь объяснить мне, что здесь происходит?

edit: Я подумал, что это я понял бы, поэтому я мог бы решить мою настоящую программную проблему, которую я заявляю здесь: Преобразование объектов Unicode с не-ASCII-символами в них в объекты строк (на Python)

Ответ 1

Это просто:.encode конвертирует объекты Unicode в строки, а .decode преобразует строки в Unicode.

Ответ 2

Почему декодирование ( "ascii" ) выдало строку юникода?

Потому что для этого decode: он декодирует строки байтов, такие как ваш ASCII, в unicode.

В вашем втором примере вы пытаетесь "декодировать" строку, которая уже является unicode, что не имеет никакого эффекта. Чтобы распечатать его на вашем терминале, Python должен кодировать его как кодировку по умолчанию, которая является ASCII, но поскольку вы не сделали этого действия явно и поэтому не указали параметр "игнорировать", он вызывает ошибку, не может кодировать символы, отличные от ASCII.

Трюк ко всему этому помнят, что decode принимает закодированную байтовую строку и преобразует ее в Unicode, а encode выполняет обратное. Это может быть проще, если вы поймете, что Unicode не является кодировкой.