Я столкнулся с проблемой печати строк, содержащих смайлики, с использованием кода Python, работающего через Idle под Ubuntu 20.04LTS. Код отлично работает в Windows 10, но когда я пытаюсь запустить его в Ubuntu, попытка просмотреть некоторые строки приводит к сбою Python/Idle без отображения каких-либо полезных сообщений об ошибках. Сами смайлики кажутся проблемой, но не со всеми смайликами. Например, 128516 (ухмыляющееся лицо с улыбающимися глазами) — это нормально, а 128077 (большой палец вверх) вызывает сбой. Оба ПК работают под управлением Python 3.8.6, и в режиме ожидания отображается один и тот же номер версии.
Я создал фрагмент кода, чтобы продемонстрировать проблему.
def make_uchr(code: str):
return chr(int(code.lstrip("U+").zfill(8), 16))
def calc1char(intdecimal):
# print() 128516 is ok... 128077 crashes on Ubuntu
strhex = hex(intdecimal)[2:]
strUhex = "U+"+strhex
stroutput = make_uchr(strUhex)
return stroutput
def main():
while True:
try:
print("Enter a decimal integer or ctrl+C to exit...")
print("Try 128516, then try 128077.")
strdecimal = input('Enter your choice: ')
intdecimal = int(strdecimal)
stroutput = calc1char(intdecimal)
print("The corresponding character is:")
print(stroutput)
print()
except KeyboardInterrupt:
break
if __name__ == '__main__':
main()
В Windows 10 этот код запускается без каких-либо проблем как при запуске через режим ожидания, так и при запуске из командной строки. В Ubuntu, когда он запускается с использованием Idle, происходит сбой Idle для некоторых кодов (например, 128077) без каких-либо видимых сообщений об ошибках. При запуске с терминала или с использованием Pycharm ожидаемый смайлик выводится на консоль. Недавно я обновился с Ubuntu 18.04LTS, и там тоже проявилась проблема.
В коде, где проблема стала очевидной, строки со смайликами будут корректно экспортироваться в текстовый файл, и у меня есть обходной путь для очистки просматриваемой строки при работе под Ubuntu, т.е.
if platform.system() == "Linux":
strmsg = (strmsg.encode("utf-8", errors='replace'))
strmsg = str(strmsg.decode("ascii", errors='replace'))
Это дает вопросительные знаки вместо других символов с кодами больше 127.
Однако мне любопытно, есть ли решение проблемы, а не обходной путь. Мы ценим любые предложения.
Вот еще один вариант с использованием примера графического интерфейса.
from tkinter import *
import tkinter as tk
def make_uchr(code: str):
return chr(int(code.lstrip("U+").zfill(8), 16))
def calc1char(intdecimal):
strhex = hex(intdecimal)[2:]
strUhex = "U+"+strhex
stroutput = make_uchr(strUhex)
return stroutput
def printtoconsole():
intdecimal = int(entry_decimal.get())
stroutput = calc1char(intdecimal)
print(stroutput)
def printtolabel():
intdecimal = int(entry_decimal.get())
stroutput = calc1char(intdecimal)
label_output.configure(text=stroutput)
def printtoentry():
intdecimal = int(entry_decimal.get())
stroutput = calc1char(intdecimal)
entry_output.delete(0,len(entry_output.get()))
entry_output.delete(0,len(entry_output.get()))
entry_output.insert(INSERT, stroutput)
def printtotext():
intdecimal = int(entry_decimal.get())
stroutput = calc1char(intdecimal)
text_box.delete("1.0", END)
text_box.insert(INSERT,stroutput)
text_box.pack()
def main():
window = tk.Tk()
window.geometry("300x300")
window.title("Emoticons !")
decimal_var = tk.StringVar()
strentryoutput_var = tk.StringVar()
strdecimal = "128516"
decimal_var.set(strdecimal)
global entry_decimal, text_box, label_output, entry_output
button1=Button(window, text="Print()", command=printtoconsole)
button2=Button(window, text="To Label", command=printtolabel)
button3=Button(window, text="To Entry", command=printtoentry)
button4=Button(window, text="To Text", command=printtotext)
entry_decimal = Entry(window, textvariable = decimal_var)
label_decimal = Label(window, text = "Enter decimal")
label_output = Label(window, text = "label to show output")
entry_output = Entry(window, textvariable = strentryoutput_var)
text_output = Text(window)
text_box = Text(text_output)
button1.place(x=10, y=50)
button2.place(x=10, y=100)
button3.place(x=10, y=150)
button4.place(x=10, y=200)
label_decimal.place(x=10, y=10)
entry_decimal.place(x=100, y=10)
label_output.place(x=100, y=100)
entry_output.place(x=100, y=150, width=50)
text_output.place(x=100, y=200, width=50, height=30)
if __name__ == '__main__':
main()
Этот новый код использует графический интерфейс, чтобы предоставить 4 кнопки для печати смайлика на консоли, в виджете метки, в виджете ввода или текстовом виджете. Взяв десятичный диапазон от 128547 до 128549, в Windows 10 смайлики печатаются с каждой кнопки без проблем. В Ubuntu 20.04 все кнопки работают правильно для 128547 и 128549. Однако для 128548 кнопка печати не выводит, но не дает сбоя. Кнопки с надписью, вводом и текстом закрывают графический интерфейс, но оставляют консоль открытой и сбрасывают, показывая === Перезапуск: Shell === ›››. После этого возможен перезапуск из окна редактора с помощью F5. В Ubuntu кнопку входа нужно дважды щелкнуть, чтобы обновить смайлик, тогда как в Windows достаточно одного щелчка. Любопытно, но, возможно, дело в другом...
chr(128516)+' '+chr(128077)
производит'???? ????'
(без заливки). Это работает с года назад. В стандартном REPL, в командной строке, я вижу только квадратики (в отличие от вас видимо). На Mac Mohave в Терминале я вижу эмодзи. В IDLE, запущенном из терминала, эти конкретные кодовые точки замораживают Shell, но не посылают сообщения на терминал. Другие кодовые точки, отличные от BMP, отображаются с их представлениями `\U000#####'. Пока Shell заморожен, окно редактора все еще работает. Для какого аспекта проблемы вы спрашиваете об исправлении? - person Terry Jan Reedy   schedule 31.10.2020