subprocess.Popen не реагирует так же, как в PyCharm, как в Windows CMD, когда есть «забавный» символ, такой как � - PullRequest
0 голосов
/ 24 апреля 2020

Прежде всего, да, я уже искал и не нашел никакого решения. Итак, проблема в следующем:

У меня есть первый python скрипт CommandLine.py, созданный в PyCharm, который запрашивает файл Json с веб-сайта, и я печатаю результат в Терминале.

    for val in my_json[:200]:
        i += 1
        print("    {} - {}".format(str(i).zfill(2), val))

Этот сценарий командной строки используется следующим образом:

python CommandLine.py --user MyUserName --password MyPWD --website www.about.com --output C:\Users\MyName\MyFolder --mail YesOrNo and so on...

Все отлично работает, я получаю результат, даже с русскими символами, японскими символами и также "забавные" персонажи в результате (как этот: �). Он работает в PyCharm и в Windows CMD одинаково («забавные» символы, подобные этому, напечатаны на обоих).

Но этот первый скрипт немного раздражает всеми аргументами (для меня, для друзей) ...), поэтому я создал второй python скрипт с именем GUI.py. Это пользовательский интерфейс Graphi c с Tkinter python lib. Вы можете использовать весь виджет Entry для выбора необходимых аргументов. Затем вы нажимаете на виджет «Кнопка» и получаете результат в текстовом виджете с именем «Консоль» (для «эмуляции» терминала). Я делаю это с subprocess.Popen следующим образом:

    cmd = 'python CommandLine.py --user MyUserName --password MyPWD 
            --website www.about.com --output C:\Users\MyName\MyFolder 
            --mail YesOrNo and so on...'

    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, encoding='utf-8')

    while True:
        returnStatus = process.poll()
        output = process.stdout.readline()
        if returnStatus is not None:
            break
        if output:
            line = output.strip() # leave the white space
            console.insert('end', line + '\n')
            console.yview_moveto(1)
            console.update()

GUI.py отлично работает в PyCharm, я получаю тот же результат, что и CommandLine.py (с нелатинским символом) без ошибки кода.

НО! Да, но. В Windows CMD этот второй скрипт GUI.py всегда вылетал с такой ошибкой кода:

Traceback (most recent call last):
  File "C:\Users\MyName\MyFolder\CommandLine.py", line 343, in <module>
    print("    {} - {}".format(str(i).zfill(2), val))
  File "C:\Python37\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 10-11: character maps to <undefined>

Я не понимаю, почему, потому что первый скрипт CommandLine.py прекрасно работает как в PyCharm, так и в Win CMD.

Является ли subprocess.Popen проблемой в CMD? Я так думаю, но не могу найти решение.

Я пробовал:

  • изменение кодировки с mbcs, ansi, ISO-8859-1 в process = subprocess.Popen(cmd, stdout=subprocess.PIPE, encoding='utf-8')

  • удалить кодировку в process = subprocess.Popen(cmd, stdout=subprocess.PIPE, encoding='utf-8')

  • добавить Shell=True

  • сделать chcp 65001 в CMD до python GUI.py

Ничто не решает проблему, все еще есть ошибка кода.

Кстати, я использую subprocess.Popen, чтобы получить "живой" вывод на печать это мой "консольный" виджет.

Где я не прав? Нужна помощь, пожалуйста. Заранее спасибо.

PS: Извините, engli sh не мой родной язык.

1 Ответ

0 голосов
/ 24 апреля 2020

Может быть попытаться вызвать подпроцесс. Открыть с помощью env={'PYTHONIOENCODING': 'utf-8'}?

В соответствии с вашей ошибкой Python выбрал «системную кодировку» (для потоков ввода-вывода) cp1252, которая, кроме несовместим с кодировкой, которую вы указываете подпроцессу ожидать не может представлять все возможные символы, которые вы получаете от своих входных данных .

PYTHONIOENCODING должен переопределить процесс Python Используется для выбора системной кодировки и просто кодирует выходной поток как utf-8, который должен быть способен представлять любой ввод и соответствовать ожиданиям вашей оболочки.

...