简体   繁体   English

Python-Swift 互操作 (PythonKit):更改默认标准输入编码

[英]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.5
  • My method for importing my Python package was by adding the path to site-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这与标准输入/标准输出不同似乎很奇怪

Update :更新 :

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM