我使用PythonKit将一个自定义Python包导入Swift,在使用XCode的Swift包(SPM)中导入一个自定义Python包。Python代码在不同的点执行f = open("somefile","r"),然后执行f.readline()。
从Swift调用时,会从Python内部引发以下错误:
File "/Users/user/[...]/lib/python3.8/site-packages/module/unihan_variants.py", line 115, in unihan_variants_dict
line = f.readline()
...
Python exception: 'ascii' codec can't decode byte 0xc2 in position 121: ordinal not in range(128)进一步研究,我发现默认的stdin解码是ascii,而不是utf-8:
let sys = Python.import("sys")
print(sys.stdin.encoding) // asciii
print(sys.stdout.encoding) // ascii当我转到我最初的Python模块时,我发现我可以通过指定PythonKit来避免f = open("somefile","r",encoding="utf-8")中的错误,但不幸的是,我在我的所有项目中都假设了utf-8。
是否有方法从XCode或PythonKit更改stdin和stdout的默认编码?
或者,是否有必要/建议返回并在所有Python代码中指定utf-8?
(这不管用):
sys.stdin.encoding = "utf-8" //Python exception: readonly attribute: file /Users/brianparker/Library/Developer/Xcode/DerivedData/Morphology-efqracfjfhxtguetmduhdszyzezb/SourcePackages/checkouts/PythonKit/PythonKit/Python.swift, line 540进一步说明:
print(platform.python_version())返回3.8.5site-packages /PythonKit中将虚拟for中的路径添加到sys.path中print(sys.getdefaultencoding())表示'utf-8‘。这与stdin/stdout的区别似乎很奇怪。最新情况:
通过设置sys.stdin.encoding环境变量,我设法让PYTHONIOENCODING指明了"utf-8“。但是,在readline()上引发相同的错误
发布于 2020-08-27 00:53:36
Python的TextIOWrapper open默认编码不是由我问题中提出的sys属性或环境变量决定的,而是默认为locale.getpreferredencoding(False)。
Python环境显示了以下内容,这解释了为什么在打开文件时通常不需要指定编码:
>>> locale.getlocale()
('en_US', 'UTF-8')
>>> locale.getpreferredencoding(do_setlocale=False)
'UTF-8'然而,Swift中的Python没有默认的区域设置(至少在我的机器上运行时是这样):
let locale = Python.import("locale")
print(locale.getlocale()) // (None, None)以下代码将在Swift应用程序中为Python设置所需的区域设置,允许TextIOWrapper在打开文件时默认为utf-8:
let locale = Python.import("locale")
if locale.getlocale().tuple2 == (Python.None,Python.None) {
locale.setlocale(locale.LC_ALL, locale: PythonObject(["en_US","UTF-8"]))
}请注意,2019年有一个Python提案来实现utf-8TextIOWrapper的默认编码,而无需检查locale,不过我不确定它是否会被采用。
https://stackoverflow.com/questions/63593949
复制相似问题