最新消息:20210917 已从crifan.com换到crifan.org

[已解决]Flask中app.logger.debug出错:UnicodeEncodeError ascii codec can’t encode characters in position 59-68: ordinal not in range(128)

Flask crifan 3230浏览 0评论

之前用Flask的logger的debug函数:

currentEvents= Event.query.all()
app.logger.debug(‘currentEvents=%s’, currentEvents)
currentEventsCount = len(currentEvents)
app.logger.debug(‘currentEventsCount=%s’, currentEventsCount)
# if currentEventsCount > 0  :
#     firstEvent = currentEvents[0]
#     app.logger.debug(‘firstEvent=%s’, firstEvent)
#     db.session.delete(firstEvent)
#     db.session.commit()
#     app.logger.debug(‘deleted firstEvent=%s’, firstEvent)
if currentUsersCount > 0  :
    firstUser = currentUsers[0]
    app.logger.debug(‘firstUser=%s’, firstUser)
    firstUserEvents = firstUser.events.all()
    print “firstUserEvents=”,firstUserEvents
    app.logger.debug(‘firstUserEvents=%r’, firstUserEvents)

结果经常出错:

<div–<——————————————————————————
Traceback (most recent call last):
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 861, in emit
    msg = self.format(record)
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 734, in format
    return fmt.format(record)
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 465, in format
    record.message = record.getMessage()
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 329, in getMessage
    msg = msg % self.args
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 59-68: ordinal not in range(128)
Logged from file db_create.py, line 103
Traceback (most recent call last):
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 861, in emit
    msg = self.format(record)
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 734, in format
    return fmt.format(record)
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 465, in format
    record.message = record.getMessage()
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 329, in getMessage
    msg = msg % self.args
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 59-68: ordinal not in range(128)
Logged from file db_create.py, line 120

<div–<——————————————————————————

DEBUG in db_create [db_create.py:123]:
currentEventsCount=1

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in db_create [db_create.py:134]:
firstUser=<User u’\u793c\u8c8c’ oswjmv4X0cCXcfkIwjoDfCkeTVVY>

<div–<——————————————————————————

firstUserEvents= [Traceback (most recent call last):
  File “db_create.py”, line 136, in <module>
    print “firstUserEvents=”,firstUserEvents
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 59-68: ordinal not in range(128)

搜:

Flask UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 59-68: ordinal not in range(128)

python – UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\xa0′ in position 20: ordinal not in range(128) – Stack Overflow

python – UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\u2013′ in position 3 2: ordinal not in range(128) – Stack Overflow

解决UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-11 – 飞翔的单车 – 51CTO技术博客

Python UnicodeEncodeError: ‘ascii’ codec can’t encode character – SaltyCrane Blog

Python: UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\xfc’ in position 11: ordinal not in range(128) at Mark Needham

Flask app.logger.debug UnicodeEncodeError: ‘ascii’ codec can’t encode characters

Flask app.logger.debug UnicodeEncodeError

Flask app.logger.debug UnicodeEncodeError ‘ascii’ codec can’t encode characters

去试了试:

python自带的logging:

import logging
logging.basicConfig(level=logging.DEBUG,
        format=’%(asctime)s %(levelname)s %(message)s’,
        filename=’flask_log.txt’,
        filemode=’a+’)
logging.debug(“firstUserEvents=%s”, firstUserEvents)

也是同样现象:

Traceback (most recent call last):
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 861, in emit
    msg = self.format(record)
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 734, in format
    return fmt.format(record)
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 465, in format
    record.message = record.getMessage()
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 329, in getMessage
    msg = msg % self.args
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 59-68: ordinal not in range(128)
Logged from file db_create.py, line 145

-》看来的确是内容有问题,无法正常打印了。。。

另外去把list中元素拿出来打印:

# app.logger.debug(‘firstUserEvents=%s’, firstUserEvents)
if len(firstUserEvents) > 0 :
    firstUserFirstEvent = firstUserEvents[0]
    app.logger.debug(‘firstUserFirstEvent=%s’, firstUserFirstEvent)

是可以的:

DEBUG in db_create [db_create.py:150]:
firstUserFirstEvent=<Event id=1 user_openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY title=讨论日历的公众号名字>

再去看看之前111行的问题

把:

app.logger.debug(u’已存在此活动 existedEvent=%r’, existedEvent)

改为:

app.logger.debug(u’已存在此活动 existedEvent=%s’, existedEvent)

就可以了。

再去处理128行的错误

改为:

currentEvents= Event.query.all()
#app.logger.debug(‘currentEvents=%s’, currentEvents)
app.logger.debug(u’currentEvents=%s’, currentEvents)

还是同样问题:

Traceback (most recent call last):
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 861, in emit
    msg = self.format(record)
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 734, in format
    return fmt.format(record)
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 465, in format
    record.message = record.getMessage()
  File “/usr/local/lib/python2.7/logging/__init__.py”, line 329, in getMessage
    msg = msg % self.args
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 59-68: ordinal not in range(128)
Logged from file db_create.py, line 129

-》现在存在一个问题:

如果是对于一个list类型的变量,其中的有些元素中的内容,包含了对应的中文字符

则去直接打印,就无法打印出来,就会报错:

UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 59-68: ordinal not in range(128)

-》而把list中的元素拿出来,单独打印,就不会出错。

想去看看:

Flask中的

app.logger 

是否可以设置默认的字符编码为UTF-8

-》这样内部解码时,对于目前大部分字符串,都是UTF-8的情况下,就不会UnicodeEncodeError了。

Flask logger default encoding

Configuration Handling — Flask Documentation (0.11)

Application Errors — Flask Documentation (0.11)

UTF-8 In Python logging, how? – Stack Overflow

15.9. logging.handlers — Logging handlers — Python 2.7.12 documentation

->

class logging.FileHandler(filename, mode=’a’, encoding=None, delay=False)

class logging.handlers.WatchedFileHandler(filename[, mode[, encoding[, delay]]])¶

class logging.handlers.TimedRotatingFileHandler(filename, when=’h’, interval=1, backupCount=0, encoding=None, delay=False, utc=False)

中是有:

encoding的

Flask app logger config

python – Flask logging – Cannot get it to write to a file – Stack Overflow

python – How to config flask app.logger from a configure file? – Stack Overflow

此处感觉时:

list中的内容,默认输出的时候,对于unicode,去调用encode,但是默认用的是ascii的,

所以中文无法正常编码,从而出错。

那就去:

把对象的__repr__变成对应的unicode,即:前面加上u:

    def __repr__(self):
        return u'<User %r %s>’ % (self.nickname, self.openid)
    def __repr__(self):
        return u'<Event id=%d user_openid=%s title=%s>’ % (self.id, self.user_openid, self.title)

然后再去打印时,用%r试试

app.logger.debug(u’currentEvents=%r’, currentEvents)
app.logger.debug(‘firstUserEvents=%r’, firstUserEvents)

结果

还是不行。

此处,暂时无法解决:

对于list类型的变量,内部的元素中包含中文,然后去调试打印,就无法正常打印

就会报错:UnicodeEncodeError

-》而对于每个元素单独的去打印出来,是可以的。

Python list debug UnicodeEncodeError

Python list print UnicodeEncodeError

Python print  list UnicodeEncodeError

Python    list UnicodeEncodeError

python – Print LIST of unicode chars without escape characters – Stack Overflow

string – Python print unicode list – Stack Overflow

Python编码和Unicode – 文章 – 伯乐在线

python – Scrapy爬虫框架抓取中文结果为Unicode编码,如何转换UTF-8编码 – SegmentFault

后来的后来,去把自己的Event类中,__repr__中,对应的中文从%s变成%r:

class Event(db.Model):
    __tablename__ = “events”
    def __repr__(self):
        #return u'<Event id=%d user_openid=%s title=%s>’ % (self.id, self.user_openid, self.title)
        return u'<Event id=%d user_openid=%s title=%r>’ % (self.id, self.user_openid, self.title)

然后再去打印输出就可以了:

DEBUG in db_create [db_create.py:129]:
currentEvents=[<Event id=1 user_openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY title=u’\u8ba8\u8bba\u65e5\u5386\u7684\u516c\u4f17\u53f7\u540d\u5b57′>]

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in db_create [db_create.py:132]:
currentEventsCount=1

<div–<——————————————————————————

<div–<——————————————————————————

DEBUG in db_create [db_create.py:143]:
firstUser=<User u’\u793c\u8c8c’ oswjmv4X0cCXcfkIwjoDfCkeTVVY>

<div–<——————————————————————————

type(firstUserEvents)= <type ‘list’>

<div–<——————————————————————————

DEBUG in db_create [db_create.py:149]:
firstUserEvents=[<Event id=1 user_openid=oswjmv4X0cCXcfkIwjoDfCkeTVVY title=u’\u8ba8\u8bba\u65e5\u5386\u7684\u516c\u4f17\u53f7\u540d\u5b57′>]

[总结]

此处用app.logger.debug去打印输出一个list类型的变量,其中list中每个元素的属性中包含中文

而内部的逻辑是:

如果去print(等价于logger.debug)一个list对象时

内部时针对list中的每一个元素,得到其__repr__的值,然后加上中括号再输出

类似于:

print ‘[‘ + ‘,’.join(“‘” + str(x) + “‘” for x in s) + ‘]’
print u'[‘ + u’,’.join(u”‘” + unicode(x) + u”‘” for x in s) + u’]’

此处,对应的list变了中的元素是Event,对应的__repr__是:

class Event(db.Model):
    __tablename__ = “events”
    # Columns
    id = db.Column(db.Integer, primary_key = True, autoincrement = True)
    #user_openid = db.Column(db.String(64))
    #user_openid = db.Column(db.String(64), db.ForeignKey(‘user.openid’))
    user_openid = db.Column(db.String(64), db.ForeignKey(‘wechat_users.openid’))
    title = db.Column(db.String(128))
    def __init__(self,
                 id,
                 user_openid,
                 title = “”):
        self.id = id
        self.user_openid = user_openid
        self.title = title
    def __repr__(self):
        #return u'<Event id=%d user_openid=%s title=%s>’ % (self.id, self.user_openid, self.title)
        return u'<Event id=%d user_openid=%s title=%r>’ % (self.id, self.user_openid, self.title)

其中的title可能包含中文字符

然后用:

currentEvents= Event.query.all()
# app.logger.debug(‘currentEvents=%s’, currentEvents)
app.logger.debug(‘currentEvents=%r’, currentEvents)

即可正常输出。

所以需要去搞清楚,什么时候应该用%r:

[基本解决]Python中格式化字符串参数%s vs %r

[总结]

截止目前,没有完全懂,但是基本上有点懂了:

1.%s=str(),在输出上述list中单个元素中包含已经是unicode的中文的字符串时,会尝试将unicode去encode编码为,用户可读的文字,由于默认使用的是ascii编码,所以导致中文无法encode,所以报错:UnicodeEncodeError

2.%r=repr(),去打印list中包含unicode的中文时,就是以unicode的方式去打印的,打印出来的是这样的:u’\u793c\u8c8c’,所以不会报错。

另:

尝试:

def __repr__(self):
    #return ‘<Event id=%d user_openid=%s title=%s>’ % (self.id, self.user_openid, self.title)
    #return u'<Event id=%d user_openid=%s title=%s>’ % (self.id, self.user_openid, self.title)
    #return u'<Event id=%d user_openid=%s title=%r>’ % (self.id, self.user_openid, self.title)
    #return ‘<Event id=%d user_openid=%s title=%r>’ % (self.id, self.user_openid, self.title)
    return ‘<Event id=%d user_openid=%s title=%s>’ % (self.id, self.user_openid, self.title.encode(“UTF-8”))

或:

        return ‘<Event id=%d user_openid=%s title=%s>’ % (self.id, self.user_openid, self.title.decode(“UTF-8”))

结果都还是不行。

UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe8 in position 0: ordinal not in range(128)
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-9: ordinal not in range(128)

有空继续研究深层次的原因。

暂时还是用:

return ‘<Event id=%d user_openid=%s title=%r>’ % (self.id, self.user_openid, self.title)

可以正常工作。

转载请注明:在路上 » [已解决]Flask中app.logger.debug出错:UnicodeEncodeError ascii codec can’t encode characters in position 59-68: ordinal not in range(128)

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
99 queries in 0.182 seconds, using 23.44MB memory