[英]Python-Swift interop (PythonKit) : Change Default Stdin Encoding
I've imported a custom Python package into Swift using PythonKit, within a Swift Package (SPM) using XCode.我已经使用 PythonKit 在使用 XCode 的 Swift 包 (SPM) 中将自定义 Python 包导入到 Swift 中。 The Python code at various points performs f = open("somefile","r")
, and then f.readline()
. Python 代码在各个点执行f = open("somefile","r")
,然后执行f.readline()
。
When invoked from Swift, the following error is raised from within Python :从 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)
Investigating further, I see that the default stdin decoding is ascii instead of utf-8 :进一步调查,我看到默认的标准输入解码是 ascii 而不是 utf-8 :
let sys = Python.import("sys")
print(sys.stdin.encoding) // asciii
print(sys.stdout.encoding) // ascii
When I go to my original Python module, I find I can avoid the error in PythonKit by specifying f = open("somefile","r",encoding="utf-8")
, but unfortunately I've just assumed utf-8 throughout all of my projects to date.当我转到我原来的 Python 模块时,我发现我可以通过指定f = open("somefile","r",encoding="utf-8")
来避免 PythonKit 中的错误,但不幸的是我只是假设 utf-迄今为止,我在所有项目中都有 8 个。
Is there a way to change default encoding for stdin and stdout from XCode or PythonKit?有没有办法从 XCode 或 PythonKit 更改 stdin 和 stdout 的默认编码?
Or is it necessary/advised to go back and specify utf-8 throughout all my Python code?或者是否有必要/建议返回并在我的所有 Python 代码中指定 utf-8?
(This doesn't work) : (这不起作用):
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
Further notes :进一步说明:
print(platform.python_version())
returns 3.8.5 print(platform.python_version())
返回 3.8.5site-packages
within the virtualenv to sys.path
in Swift/PythonKit我导入 Python 包的方法是将 virtualenv 中site-packages
的路径添加到 Swift/PythonKit 中的sys.path
print(sys.getdefaultencoding())
indicates 'utf-8'. print(sys.getdefaultencoding())
表示 'utf-8'。 It seems weird that this differs from stdin/stdout这与标准输入/标准输出不同似乎很奇怪 I've managed to get sys.stdin.encoding
to indicate "utf-8" by setting the PYTHONIOENCODING
environment variable.通过设置PYTHONIOENCODING
环境变量,我设法让sys.stdin.encoding
指示“utf-8”。 However the same error gets thrown at readline()
但是在readline()
抛出了同样的错误
Python's TextIOWrapper open
's default encoding isn't determined by the sys
properties or environment variables proposed in my question. Python 的 TextIOWrapper open
的默认编码不是由我的问题中提出的sys
属性或环境变量决定的。 Instead, it defaults to locale.getpreferredencoding(False)
.相反,它默认为locale.getpreferredencoding(False)
。
My Python environment shows the following, which explains why I typically don't need to specify an encoding when opening a file :我的 Python 环境显示以下内容,这解释了为什么我在打开文件时通常不需要指定编码:
>>> locale.getlocale()
('en_US', 'UTF-8')
>>> locale.getpreferredencoding(do_setlocale=False)
'UTF-8'
Python within Swift however does not have a default locale (at least when run on my machine):然而,Swift 中的 Python 没有默认语言环境(至少在我的机器上运行时):
let locale = Python.import("locale")
print(locale.getlocale()) // (None, None)
The following code will set the desired locale for Python within the Swift app, allowing TextIOWrapper to default to utf-8 when opening files :以下代码将在 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"]))
}
Note that there's a Python proposal from 2019 to make utf-8 TextIOWrapper's default encoding without checking locale
, though I'm not sure if it will be adopted.请注意,从 2019 年开始,有一个Python 提案在不检查locale
的情况下使 utf-8 TextIOWrapper 的默认编码,但我不确定它是否会被采用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.