Python 3.6对于Windows平台下现代字符串的优化
acmilan2017/01/19软件综合 IP:内蒙古

一、控制台(PEP 528)

Python 2.x/3.x在Windows平台,长期以来对于控制台输入输出的做法,都是转换为OEM编码按字节输入输出。但是事实上OEM编码已经过时,在输出某些文本的时候,经常会出现一些OEM编码不支持的字符,导致print直接崩溃,让人感到非常棘手。

Python迟迟未改变可能是因为:长期以来(直到Windows 8.1)Windows控制台都在使用OEM点阵字体,根本无法显示Unicode字符,所以大多数情况下是不可能发现控制台居然还能显示Unicode字符的。直到Windows 10,控制台才开始使用可以显示Unicode字符的TrueType字体。

根据最新的Python 3.6.0发行说明(XXXXXXXXXXXXXXXXXXXXXX/downloads/release/python-360/),Python 3.6加入了以下特性:

在交互模式下,XXXXXXdin/stdout/stderr将使用UTF-8编码,.encoding返回'utf-8',而在重定向模式下,将继续使用以前默认的ANSI编码,.encoding返回'cpXXX'。(顺便说一下,重定向模式下Python 2.7这里居然返回空白,需要XXXXXXXXXtpreferredencoding()。。。)

可使用%PYTHONLEGACYWINDOWSSTDIO%环境变量以阻止交互模式下使用UTF-8,改为使用以前的OEM编码,.encoding将返回'cpXXX',代码页可能和ANSI编码不同。

虽然重定向模式下使用的仍然是ANSI编码,但是可以设置环境变量%PYTHONIOENCODING%为utf-8强制输出为UTF-8,实际上也不是问题,只是为兼容性做的让步而已。

也就是说,现在已经不用担心Python 3在print的时候会莫名其妙崩溃了。

二、文件名(PEP 529)

除了控制台以外,对于以字节字符串表示的文件名,也将以UTF-8处理,XXXXXXtfilesystemencoding()将返回'utf-8'。

可以使用%PYTHONLEGACYWINDOWSFSENCODING%环境变量和sys._enablelegacywindowsfsencoding()改回原来的MBCS方式,XXXXXXtfilesystemencoding()将返回原来的'mbcs'。

不过其实这个改变影响并不大,Python早就可以在Windows下使用Unicode文件名了。

[修改于 7年11个月前 - 2017/01/20 01:05:59]

来自:计算机科学 / 软件综合
4
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
acmilan 作者
7年11个月前 修改于 7年11个月前 IP:浙江
829622
Python 3.6可以下载zip版本用于再分发,不过由于它是用VC++2015编译的,在Windows 7等老系统运行会报缺少Universal CRT DLLs。这些DLL可以在Windows 10 SDK里面找到。

这里上传一份目前的最新版本(10.0.14393.33),与Python解压到相同目录即可使用。


attachment icon UCRTBASE_DLL_14393_33_x86_x64.rar 1.52MB RAR 23次下载
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan作者
7年11个月前 修改于 7年11个月前 IP:内蒙古
829633

如果必须用老版本的话,有一个解决方法,在IDLE中运行脚本就可以避免出现print崩溃。原因是IDLE是支持Unicode的。

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan作者
7年11个月前 修改于 7年11个月前 IP:内蒙古
829634
其实OEM代码页主要是给DOS程序使用的,除了微软自己以外没人用OEM代码页,都是用的ANSI代码页。用OEM代码页只能保证显示正确,但是却带来了更多的麻烦和问题。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan作者
7年11个月前 修改于 7年11个月前 IP:浙江
829756

Python 2.7使用from __future__ import division,absolute_import,print_function,unicode_literals,可以在语法层面开启Python 3模式。

Python 2/3在细节上的区别更多,比如模块、类、函数名称,基类object之类的,真正移植起来要处理的东西很多,远不止四个import这么简单,但是以后想要移植到或者兼容Python 3.x就会方便很多,因为这四个功能是Python 2和Python 3移植困难的最主要原因。

如果要加中文的话,还要加上# -*- encoding: utf-8 -*-,因为Python 2.7默认认为脚本是ISO-8859-1。

<code class="language-py">#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from __future__ import division,absolute_import,print_function,unicode_literals

import sys;
import os;

print("Python版本:" + str(sys.version_info.major));
</code>

特别是如果需要跨平台的话,即使是想要继续使用Python 2,也建议加上encoding声明和unicode_literals,不然就只能用英文了。

<code class="language-py">#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
</code>
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
acmilan
进士 学者 笔友
文章
461
回复
2934
学术分
4
2009/05/30注册,5年10个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}