Странное поведение pycharm?

Добрый день, друзья!

Помогите пожалуйста понять что я делаю не так:

Создаем виртуальное окружение python3:
cd python/envs/
virtualenv test_venv
. test_venv/bin/activate
pip install feedparser

далее запускаем код:
import feedparser
rss=feedparser.parse('https://www.lostfilm.tv/rssdd.xml')
print(rss)

происходит что и ожидалось в вывод валится содержимое rss, в читаемой кодировке.

Теперь
Запускаем pycharm.
Добавляем окружение созданное вначале.
Создаем проект, указываем в качестве интерпритатора добавленное окружение.
Cоздаем файл lf.py. В него копируем тот же самый код.
Запускаем.

видим exception
File "/home/nikitos/PycharmProjects/untitled2/lf.py", line 3, in <module>
    print(feedparser.parse('https://www.lostfilm.tv/rssdd.xml'))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 488-492: ordinal not in range(128)

почему так происходит?
  • Вопрос задан
  • 3455 просмотров
Решения вопроса 3
trapwalker
@trapwalker Куратор тега Python
Программист, энтузиаст
Сейчас я проясню ситуацию=).
Текст бывает либо в какой-то кодировке (cp1251, utf-8, win866, ascii, и т.д.), тогда это байты; либо в юникоде (это, как бы, абстрактное представление символов), тогда это строки из абстрактных юникодовых символов.
Все файлы, потоки ввода-вывода и т.д. у нас в компьютере работает с байтами, а не с абстрактными юникодовыми символами. Это значит, что перед выводом в файл или консоль должно производиться кодирование юникода в конкретную кодировку.
Кодировка -- это способ представить байтами абстрактных символов юникода. Каждый юникодовый символ, в зависимости от кодировки, будет задаваться одним или более байтом. Некоторые абстрактные символы не поддерживаются некоторыми кодировками.

Так, например, кодировка ascii поддерживает только стандартные 128 символов и при попытке конвертировать в неё (явно или неявно) букву "Ж", будет такая же ошибка как у вас. Надо полагать метод parse в вашем случае возвращает юникод, а оператор print делает неявное преобразование в кодировку по умолчанию (ascii, судя по сообщению об ошибке).
Осталось выяснить в каких случаях как определяется кодировка по умолчанию.
Артём Клименко правильно предложил в своём ответе проверить что берётся в качестве кодировки по умолчанию в том и другом случае.
Однако решением проблемы должно быть явное преобразование текста в нужную кодировку. Я в таких случаях придерживаюсь следующих правил:
  • Всё, что приходит в программу, привожу в юникод (если это не произошло неявно в той библиотеке, посредством которой я получил данные).
  • В программе работаю с текстом только в юникоде (если речь не идёт о каких-то низкоуровневых операциях над байтами, вроде парсинга протоколов и прочего.
  • Перед выводом конвертирую текст в нужную кодировку или настраиваю потоки вывода на автоматическое преобразование.
  • Когда не понятно в какой кодировке делать вывод, руководствуюсь следующими правилами:
    • Выходной поток -- это виндовый stdout и в нём не задана кодировка (bat-файлы, консоль) -- cp866
    • Файлы, БД и прочее, что поддерживает юникод и сделано правильно -- UTF-8
    • Когда в винде не помогают пердыдущие пункты -- cp1251
    • В других операционках utf-8.


Подчеркиваю. Если выходной поток сконфигурирован на ascii, а у нас в программе могут попасться не-ascii символы, то нужно приводить текст в какую-то кодировку (см выше)), а иначе ничего не трогаем и пишем юникод.
Ответ написан
Комментировать
сталкивался с подобным, и тут не столько пайчарм виноват, вопрос в том в какой кодировке выводится информация, если консоль для вывлда на текущий момент не юникодовая, тут и начинаются такие проблемы.
гляньте что вам вернёт:
import sys, locale, os, codecs 
print(sys.stdout.encoding)
print(sys.stdout.isatty())
print(locale.getpreferredencoding())
print(sys.getfilesystemencoding())
Ответ написан
Комментировать
dimonchik2013
@dimonchik2013
non progredi est regredi
поведение не странное, поведение првавильное

можете прорделать то же в IDLE, увидиите, что там все ок,
но на этот ОК нельзя полагаться: будете забывать о перекодировке и проверке кодировки, когда это необходимо

проделайте то же в консоли (не в IDLE) и там уже будет не ОК

рецепт: не выводите в консоль, пишите в файл или в базу, все будет работать
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
mututunus
@mututunus
Backend developer (Python, Golang)
Попробуйте добавить
from __future__ import unicode_literals
Ответ написан
Комментировать
chukov
@chukov Автор вопроса
Большое вам спасибо!
print(sys.stdout.encoding)
В pycharm поменял кодировку проекту на utf8 и все заработало.
Сергей Паньков отдельное спасибо за ликбез, после прочтения, в голове начала складываться мозайка понимания:)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы