Функция print() Python 3 с символами фарси/арабский

Я упростил свой код для лучшего понимания. вот проблема:

случай 1:

# -*- coding: utf-8 -*-

text = "چرا کار نمیکنی؟" # also using u"...." results the same
print(text)

выход:

UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-2: character maps to <undefined>

случай 2:

text = "چرا کار نمیکنی؟".encode("utf-8") 
print(text)

нет выхода.

случай 3:

import sys

text = "چرا کار نمیکنی؟".encode("utf-8")
sys.stdout.buffer.write(text)

выход:

چرا کار نمیکنی؟

Я знаю, что случай 3 работает как-то, но я хочу использовать другие функции, такие как print(), write (str()),....

Я также прочитал документацию python 3 относительно Unicode здесь.

а также прочитать десятки Q & A в stackoverflow.

и здесь - длинная статья, объясняющая проблему и ответ для python 2.X

простой вопрос:

как печатать не-ASCII-символы, такие как фарси или арабский, используя функцию python print()?

update 1: так как многие ребята говорят, что проблема связана с терминалом, который я тестировал:

случай 4:

text = "چرا کار نمیکنی؟" .encode("utf-8")# also using u"...." results the same
print(text)

терминал:

python persian_encoding.py > test.txt

test.txt:

b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f'

очень важное обновление:

после некоторого времени, играя вокруг этой проблемы, наконец, я нашел другое обходное решение, чтобы заставить cmd.exe выполнять работу (без необходимости использования сторонних программ, таких как ConEmu или...):

небольшое объяснение сначала:

наша основная проблема не касается Python. это проблема с набором символов командной строки в Windows (для полного объяснения проверьте Arman Answer) поэтому... если вы измените набор символов командной строки Windows на UTF-8 вместо стандартного ascii, тогда Командная строка сможет взаимодействовать с символами UTF-8 (например, с фарси или арабским), это решение не гарантирует хорошего представления (поскольку они будут напечатаны как маленькие квадраты), но это хорошее решение, если вы хотите иметь ввод/вывод файлов в python с символами UTF-8.

Шаги:

перед запуском python из командной строки введите:

chcp 65001

теперь запускайте свой код на Python, как всегда.

python testcode.py

привести к случаю 1:

?????? ??? ??????

он работает без ошибок.

скриншот:

введите описание изображения здесь

для получения дополнительной информации о том, как установить 65001 в качестве набора символов по умолчанию, .

Ответы

Ответ 1

Ваш код верен, поскольку он работает на моем компьютере с Python 2 и 3 (я на OS X):

~$ python -c 'print "تست"'
تست
~$ python3 -c 'print("تست")'
تست

Проблема заключается в том, что ваш терминал не может выводить символы Unicode. Вы можете проверить это, перенаправив свой вывод в файл, например python3 my_file.py > test.txt, и откройте файл с помощью редактора.

Если вы находитесь в Windows, вы можете использовать терминал, например Console2 или ConEmu, что делает юникод лучше, чем приглашение Windows.

Вы также можете столкнуться с ошибками с этими терминалами из-за неправильных кодовых страниц/кодировок Windows. Существует небольшой пакет python, который их исправляет (правильно устанавливает):

1- Установите this pip install win-unicode-console

2- Поместите это в начало файла python:

try:
    # Fix UTF8 output issues on Windows console.
    # Does nothing if package is not installed
    from win_unicode_console import enable
    enable()
except ImportError:
    pass

Если при перенаправлении к файлу возникли ошибки, вы можете исправить его с помощью настроек io-кодирования:

В командной строке Windows:

SET PYTHONIOENCODING=utf-8

В терминале Linux/OS X:

export PYTHONIOENCODING=utf-8

Некоторые точки

  • Нет необходимости использовать синтаксис u"aaa" в python 3. Строковые литералы по умолчанию имеют unicode.
  • Стандартное кодирование файлов - это UTF8 в python 3, поэтому комментарий объявления кодирования (например, # -*- coding: utf-8 -*-) не требуется.

Ответ 2

Вывод будет зависеть в основном от того, на какой платформе & терминал вы запускаете свой код. Давайте рассмотрим приведенный ниже фрагмент для разных терминалов Windows, работающих либо с 2.x, либо 3.x:

# -*- coding: utf-8 -*-
import sys

def case1(text):
    print(text)

def case2(text):
    print(text.encode("utf-8"))

def case3(text):
    sys.stdout.buffer.write(text.encode("utf-8"))

if __name__ == "__main__":
    text = "چرا کار نمیکنی؟"

    for case in [case1, case2, case3]:
        try:
            print("Running {0}".format(case.__name__))
            case(text)
        except Exception as e:
            print(e)

        print('-'*80)

Результаты

Python 2.x

Sublime Text 3 3122

    Running case1
    'charmap' codec can't encode characters in position 0-2: character maps to <undefined>
    --------------------------------------------------------------------------------
    Running case2
    b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f'
    --------------------------------------------------------------------------------
    Running case3
    چرا کار نمیکنی؟--------------------------------------------------------------------------------

ConEmu v151205

    Running case1
    ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ
    --------------------------------------------------------------------------------
    Running case2
    'ascii' codec can't decode byte 0xda in position 0: ordinal not in range(128)
    --------------------------------------------------------------------------------
    Running case3
    'file' object has no attribute 'buffer'
    --------------------------------------------------------------------------------

Командная строка Windows

    Running case1
    ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ
    --------------------------------------------------------------------------------

    Running case2
    'ascii' codec can't decode byte 0xda in position 0: ordinal not in range(128)
    --------------------------------------------------------------------------------

    Running case3
    'file' object has no attribute 'buffer'
    --------------------------------------------------------------------------------

Python 3.x

Sublime Text 3 3122

    Running case1
    'charmap' codec can't encode characters in position 0-2: character maps to <undefined>
    --------------------------------------------------------------------------------
    Running case2
    b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f'
    --------------------------------------------------------------------------------
    Running case3
    چرا کار نمیکنی؟--------------------------------------------------------------------------------

ConEmu v151205

    Running case1
    'charmap' codec can't encode characters in position 0-2: character maps to <undefined>
    --------------------------------------------------------------------------------
    Running case2
    b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f'
    --------------------------------------------------------------------------------
    Running case3
    ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ--------------------------------------------------------------------------------

Командная строка Windows

    Running case1
    'charmap' codec can't encode characters in position 0-2: character maps to <unde
    fined>
    --------------------------------------------------------------------------------

    Running case2
    b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda
    \xa9\xd9\x86\xdb\x8c\xd8\x9f'
    --------------------------------------------------------------------------------

    Running case3
    ┌åÏ▒Ϻ ┌®ÏºÏ▒ ┘å┘à█î┌®┘å█îσ----------------------------------------------------
    ----------------------------

Как вы можете видеть, только использование возвышенного терминала text3 (case3) работает нормально. Другие терминалы не поддерживали персидский язык. Главное здесь, это зависит от того, какой терминал и платформа вы используете.

Решение (специфичное для ConEmu)

Современные терминалы, такие как ConEmu, позволяют работать с кодировкой UTF8 как здесь, поэтому попробуйте:

chcp 65001 & cmd

И затем снова запустите script против 2.x и 3.x:

Python2.x

Running case1
��را کار نمیکنی؟[Errno 0] Error
--------------------------------------------------------------------------------
Running case2
'ascii' codec can't decode byte 0xda in position 0: ordinal not in range(128)
--------------------------------------------------------------------------------
Running case3
'file' object has no attribute 'buffer'
--------------------------------------------------------------------------------

Python3.x

Running case1
چرا کار نمیکنی؟
--------------------------------------------------------------------------------
Running case2
b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f'
--------------------------------------------------------------------------------
Running case3
چرا کار نمیکنی؟--------------------------------------------------------------------------------

Как вы можете видеть, теперь результат был успешным с python3 case1 (печать). Итак... мораль басни... узнайте больше о своих инструментах и ​​о том, как правильно их настроить для ваших случаев использования; -)

Ответ 3

Я не могу воспроизвести проблему. Вот мой script p.py:

text = "چرا کار نمیکنی؟"
print(text)

И результат python3 p.py:

چرا کار نمیکنی؟

Вы уверены, что используете python 3? С помощью python2 p.py:

SyntaxError: Non-ASCII character '\xda' in file p.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Ответ 4

И если вы выполните text.encode("utf-8") -part, он будет отображаться как b'\xda\x86\xd8\xb1\xd8\xa7 \xda\xa9\xd8\xa7\xd8\xb1 \xd9\x86\xd9\x85\xdb\x8c\xda\xa9\xd9\x86\xdb\x8c\xd8\x9f' (на моей машине).

ИЗМЕНИТЬ Извините за редактирование, но я не могу прокомментировать (потому что недостаточно репутации)

Даже на python 2.7 работает print(text). Здесь вы можете найти эту ссылку, которую я только что создал.