Расшифровка под капотом в питоне - PullRequest
0 голосов
/ 23 мая 2018

Я новичок в python и получаю журнал ошибок 'ascii codec не может декодировать байт ...'.Ошибка в строке

status = task.status_text()

из кода

text = u"*{username}* moved a `Task` on <{url}|Card {prefix}-{local_id}> to `{status}`".format(
        username = slack_util.user_name(user),
        url = url,
        prefix = project.prefix,
        local_id = story.local_id,
        status=task.status_text()
    )

, а функция status_text такова:

def status_text(self):
        si = self.status * 10 - 10
        ei = self.status * 10
        return self.story.project.task_status_names[si:ei].strip()

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

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

В Python 2, когда вы смешиваете unicode и str в одном и том же выражении, он должен decode() str или encode() unicode автоматически заставить их работать.И делает это, используя кодировку по умолчанию, которая обычно 'ascii'.Таким образом, если какая-либо из ваших строк не является ASCII, вы получите ошибку, подобную этой.

Это происходит, когда вы вызываете format для объекта unicode и передаете ему значение strдля форматирования:

>>> u'{}'.format('abc')
u'abc'
>>> u'{}'.format('abc\xe9')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 3: ordinal not in range(128)

И обратите внимание, что в вашем коде есть такая строка.Очевидно, что task.status_text() возвращает строку, которая не является ASCII, точно так же, как 'abc\xe9' в моем более простом примере.


Чтобы это исправить, либо нужно быть осторожным, чтобы всегда использовать одинвведите последовательно:

>>> print '{}'.format('abc\xe9')
abcé

В идеале вы можете настроить интерфейс базы данных так, чтобы он возвращал unicode вместо закодированного str, во-первых:

>>> print u'{}'.format(u'abcé')
abcé

Если нет, вам нужночтобы сделать decode или encode явным, чтобы вы могли указать правильную кодировку:

>>> print u'{}'.format('abc\xe9'.decode('latin-1'))
abcé

Конечно, я понятия не имею, откуда исходит ваш status_text, поэтому я понятия не имею,это латиница-1.(На самом деле, UTF-8, вероятно, более вероятен.) Но вы должны знать, или иметь возможность искать его или иным образом узнавать.


Если вы думаете, что это огромная боль… ну,именно поэтому Python 3 был изобретен более десяти лет назад.Все эти проблемы исчезнут, как только вы решите обновить.

0 голосов
/ 23 мая 2018

Здесь я попробовал ваш код со следующим вводом для генерации текстового формата:

text = u"*{username}* moved a `Task` on <{url}|Card {prefix}-{local_id}> to `{status}`".format(
        username = 'rahul',
        url = 'www.google.com',
        prefix = 'Pro',
        local_id = '12',
        status='Hello'
    )
print text

И вывод, который я получил:

*rahul* moved a `Task` on <www.google.com|Card Pro-12> to `Hello`
[Finished in 0.0s]  

Это означает, что значения, возвращаемые вашими переменнымивнутри метода форматирования не так, как указано выше, я передаю. Итак, сначала попробуйте распечатать переменную этих пятерок, что именно они возвращают значения.

...