#python #swift #tensorflow #interop
#python #swift #тензорный поток #взаимодействие #swift-pythonkit
Вопрос:
Я импортировал пользовательский пакет Python в Swift с помощью PythonKit, внутри пакета Swift (SPM) с использованием XCode. Код 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 во всех своих проектах на сегодняшний день.
Есть ли способ изменить кодировку по умолчанию для stdin и stdout из XCode или PythonKit?
Или необходимо / рекомендуется вернуться и указать utf-8 во всем моем коде Python?
(Это не работает) :
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.5- Мой метод импорта моего пакета Python заключался в добавлении пути к
site-packages
в virtualenv кsys.path
в Swift / PythonKit print(sys.getdefaultencoding())
указывает на ‘utf-8’. Кажется странным, что это отличается от stdin / stdout
Обновить :
Мне удалось sys.stdin.encoding
указать «utf-8», установив PYTHONIOENCODING
переменную среды. Однако та же ошибка возникает при readline()
Ответ №1:
Кодировка по умолчанию Python TextIOWrapper open
не определяется sys
свойствами или переменными среды, предложенными в моем вопросе. Вместо этого по умолчанию используется locale.getpreferredencoding(False)
.
Моя среда Python показывает следующее, что объясняет, почему мне обычно не нужно указывать кодировку при открытии файла :
>>> locale.getlocale()
('en_US', 'UTF-8')
>>> locale.getpreferredencoding(do_setlocale=False)
'UTF-8'
Однако Python в Swift не имеет языкового стандарта по умолчанию (по крайней мере, при запуске на моем компьютере):
let locale = Python.import("locale")
print(locale.getlocale()) // (None, None)
Следующий код установит желаемый язык для Python в приложении Swift, позволяя 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-8 без проверки locale
, хотя я не уверен, будет ли она принята.