Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员
查看: 10|回复: 0

Python print报ascii编码异常的靠谱解决办法

[复制链接]
  • TA的每日心情
    奋斗
    昨天 19:16
  • 签到天数: 66 天

    [LV.6]常住居民II

    1348

    主题

    1348

    帖子

    3万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32858
    发表于 2021-6-11 00:37:20 | 显示全部楼层 |阅读模式

    之前遇到此异常UnicodeEncodeError: 'ascii' codec can't encode characters...,都是用这种方式解决:sys.setdefaultencoding('utf-8')

    今天看到如下文章,阐述了此方式的弊端:

    http://blog.ernest.me/post/python-setdefaultencoding-unicode-bytes

    但此文章只考虑了未使用第三方库的情况下的解决办法,而第三方库里如果也有print的话,就束手无策了,总不能把第三方的所有print都加上encode吧。

    另外此文中说的修改编码为utf8的隐患,其实都是因为没有使用unicode字符串或两种字符串混用而已,如果项目中规定只可使用u'unicode字符串',上述隐患即可基本避免。归根结底最大的风险就是第三方库的不可控,print编码和unicode字符串都不可控,所以不能使用setdefaultencoding。

     

    我这次是在用Java启动python时,print中文,就会报ascii的异常,我发现此种情况下sys.stdout.encoding其实为None,而Ubuntu中普通命令行时此变量则是UTF-8。

    那如何修改sys.stdout.encoding呢?(直接修改会报错TypeError: readonly attribute)

    所以最终找到http://www.macfreek.nl/memory/Encoding_of_Python_stdout

    python2修改方式(python3略不同,原文中也有写)

    1 if sys.stdout.encoding != 'UTF-8':
    2     sys.stdout = codecs.getwriter('utf-8')(sys.stdout, 'strict')
    3 if sys.stderr.encoding != 'UTF-8':
    4     sys.stderr = codecs.getwriter('utf-8')(sys.stderr, 'strict')

    这样就完美解决输出中文时的ascii编码异常了,而且也不用重新设置sys的默认编码。

     

    后记:

    理想很丰满,现实很骨感,有的时候还是要用setdefaultencoding的。。。

    比如不仅是print,还涉及到遍历文件,并且要写结果文件时,在shell下运行正常,可能用java启动的python就会报编码问题,如果不改java那边,可能就要选择setdefaultencoding了,因为如果兼容了java,可能shell下又会报编码问题了,按下葫芦浮起瓢。当然如果把相关几个涉及编码的地方包个函数,在里面根据情况来切换也行,如果时间允许也可以考虑。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2021-6-22 22:36 , Processed in 0.053240 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表