【问题标题】:Logging fails with UnicodeEncodeError when attempting to use .format(myVar) where myVar contains unicode characters尝试使用 myVar 包含 unicode 字符的 .format(myVar) 时,记录失败并出现 UnicodeEncodeError
【发布时间】:2019-06-04 17:33:45
【问题描述】:

我在日志中使用 str.format() 函数:

    logging.debug('querying author: {}, track: {}'.format(artist)

当艺术家变量包含这样的unicode字符时:u'Ry Cooder & Ali Farka Tour\xe9'格式失败如下:

    artists = {u'A Tribe Called Quest': [u"People's Instinctive Travels and the Paths of Rhythm"],
     u'All': [u'Percolater', u'Pummel'],
     u'Andrew Bird': [u'The Mysterious Production of Eggs',
                      u'Noble Beast',
                      u'Break It Yourself',
                      u'Weather Systems',
                      u'Hands of Glory'],
     u'April Smith And The Great Picture Show': [u'Songs For A Sinking Ship'],
     u'Ry Cooder & Ali Farka Tour\xe9': [u'Talking Timbuktu']}

    for each in artists:
        print 'this is the string: u"{}"'.format(each)

    >>> this is the string: A Tribe Called Quest
    >>> ---------------------------------------------------------------------------
    >>> UnicodeEncodeError                        Traceback (most recent call last)
    >>> <ipython-input-28-4770333e9fbf> in <module>()
    >>>       1 for each in artists:
    >>> ----> 2     print 'this is the string: {}'.format(each)

    >>> UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 26: ordinal not in range(128)

对于所有日志记录实例,处理此问题的正确方法是什么?我知道我可以使用 str.encode('ascii', 'ignore') 转储 unicode 字符并回避这个问题:

    for each in artists:
        print 'this is the string: {}'.format(each.encode('ascii', 'ignore'))

    >>> this is the string: A Tribe Called Quest
    >>> this is the string: Ry Cooder & Ali Farka Tour
    >>> this is the string: Andrew Bird
    >>> this is the string: All
    >>> this is the string: April Smith And The Great Picture Show

上述解决方案意味着寻找每个可能遇到 unicode 字符的日志记录实例并添加 str.encode() 并且感觉不是很“pythonic”。

2019 年 1 月 2 日编辑

当另一个模块的日志记录尝试处理这些数据时,这尤其成问题。除了确保 unicode 字符永远不会超出我的受控环境之外,还有其他解决方案吗?

结束编辑

有没有更优雅、更合适的方法来处理这个问题?使用 str.format() 函数时,处理 unicode 的适当方法是什么?

为了完整性:

由于我与之交互的 API 需要 UTF-8,因此总是强制艺术家变量使用以下代码进行 unicode。

        def _forceUnicode(self, text):
            '''
            force text into unicode
            https://gist.github.com/gornostal/1f123aaf838506038710
            '''
            return text if isinstance(text, unicode) else text.encode('utf-8')

【问题讨论】:

  • 我还找到了使用u'logger text {}'.format(artist)this 解决方案,但它与上面描述的 encode() 解决方案非常相似,并且需要对每个解决方案进行编辑。单身的。记录线。
  • 我认为u'{}' 解决方案没有任何问题,您不妨将所有日志记录更改为 unicode。使用其中一个可能不会导致问题,但是混合 unicode 和常规字符串会很棘手。
  • 写一个 str() 的超类并添加一个 .logformat() 方法会更 Pythonic 吗?我可以找到/替换所有日志行,似乎应该有更好的方法。

标签: python-2.7


【解决方案1】:

TL:DR:text.encode('utf-8') 应为 text.decode('utf-8')str.format() 语句应以“u”开头,如 u'some text: {}'.format(myVar)

长答案: 我根本不明白“utf-8”和“unicode”之间的区别。我现在不能说我完全理解它,但我现在意识到我试图将我的所有文本强制转换为 unicode 实际上是在强制它为 utf-8 和 str.format() 被我喂它的 utf-8 窒息.

上面的函数应该是

        def _forceUnicode(text):
            '''
            force text into unicode
            https://gist.github.com/gornostal/1f123aaf838506038710
            '''
            return text if isinstance(text, unicode) else text.decode('utf-8')  

这会将所有内容强制转换为 unicode,str.format() 的行为符合预期,但需要表明它是 unicode 字符串 print u'{}'.format()

    for each in artists:
        print u'this is the string: {}'.format(each)

    >>> this is the string: A Tribe Called Quest
    >>> this is the string: Ry Cooder & Ali Farka Touré
    >>> this is the string: Andrew Bird
    >>> this is the string: All
    >>> this is the string: April Smith And The Great Picture Show

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多