我对此有些困惑open
。我正在运行Windows 10,当我打电话时sys.getfilesystemencoding
会得到提示mbcs
,如果我将文件名传递open
给例如:
open('Meow!.txt')
假设源文件的编码为utf-8。是否使用设置为默认Windows ANSI代码页的open
编码对文件名'Meow!.txt'
进行mbcs
编码?然后将请求传递给OS?
一般来说,open
在2.X和str
3.X中将文件名传递为Unicode时会发生什么?
当文件名bytes
在3.X或str
2.X中作为对象传递时,会覆盖文件名的默认自动编码吗?
open
确切地说,这是使用2.7中的内置功能时内部发生的情况:
Python设置了一个常量,该常量命名了文件名的默认编码,该常量被调用Py_FileSystemDefaultEncoding
并且随平台而变化。最终,当其值设置为Null时,Python将尝试获取平台的默认编码(如果存在):
/*bltinmodule.c*/
/* The default encoding used by the platform file system APIs
Can remain NULL for all platforms that don't have such a concept
*/
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
const char *Py_FileSystemDefaultEncoding = "mbcs";
#elif defined(__APPLE__)
const char *Py_FileSystemDefaultEncoding = "utf-8";
#else
const char *Py_FileSystemDefaultEncoding = NULL; /* use default */
#endif
Py_FileSystemDefaultEncoding
使用“ mbcs”(多字节字符集)Windows编码,可以检查Py_FileSystemDefaultEncoding
usingsys.getfilesystemencoding()
调用的值:
Python 2.7文档:
sys.getfilesystemencoding()
在Windows NT +上,文件名本机为Unicode,因此不执行任何转换。
getfilesystemencoding()
仍然返回“ mbcs”,因为这是应用程序在明确希望将Unicode字符串转换为与用作文件名时等效的字节字符串时应使用的编码。
因此,例如,假设一个带有汉字的文件名,为简单起见,我将使用U + 5F08中国象棋CJK作为我要编写的文件名:
>>> f = open(u'\u5F08.txt', 'w')
>>> f
<open file u'\u5f08', mode 'w' at 0x000000000336B1E0>
open
在2.X和str
3.X中将文件名传递为Unicode时会发生什么?这个答案取决于平台。例如,在Windows中,不需要将Unicode字符串转换为任何编码,甚至不需要使用默认文件系统编码“ mbcs”,就可以证明:
>>> f = open(u'\u5F08.txt'.encode('mbcs'), 'w')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 22] invalid mode ('w') or filename: '?.txt'
顺便说一句,即使您使用“ utf-8”编码,也不会获得正确的文件名:
>>> f = open(u'\u5F08.txt'.encode('utf8'), 'w')
如果您在Windows上而不是弈.txt进行检查,这将为您提供弈.txt文件名。总之,显然没有Unicode文件名的转换。我认为这条规则也适用。由于在2.X中是原始字节字符串,因此Python不会神奇地选择编码**但是我无法验证这一点,并且Python可能会使用“ mbcs”编码进行解码。可以通过使用“ mbcs”代码页字符集之外的字符来验证我是否相信,但这又取决于您的Windows语言环境设置。Windows实现中的底层封装了太多内容。如果有内存,我认为“ mbcs”现在被视为Windows API的遗留物。Python 3.6改用UTF-8,str
str
str
确实,似乎问题是Windows API及其实现的深层问题,而不是Python本身的实现。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句