Как упоминали ΤΖΩΤΖΙΟΥ и Старбак, проблема заключается в кодовой странице консоли, которая в вашем случае 866 (в русской локализации Windows), а не 1251. Просто запустите chcp
в консоли.
Проблема та же, что и при выводе Unicode в консоль Windows. К сожалению, вам нужно будет, по крайней мере, запросить и псевдоним для юникода как 'cp866' в кодировках \ aliases.py (или сделать это программно при запуске скрипта) и изменить кодовую страницу консоли на 65001 перед запуском блокнота и затем вернуть его обратно .
chcp 65001 & c:\WINDOWS\notepad.exe nèw.txt & chcp 866
Кстати, чтобы иметь возможность запускать команду в консоли и правильно видеть имя файла, вам нужно будет изменить шрифт консоли на Lucida Console в свойствах окна консоли.
Это может быть еще хуже: вам нужно будет изменить кодовую страницу текущего процесса. Для этого вам нужно либо запустить chcp 65001 прямо перед запуском скрипта, либо использовать pywin32 для этого внутри скрипта.
У меня нет ответа для вас, но я провел много исследований по этой проблеме. Python преобразует весь вывод (включая системные вызовы) в тот же символ, что и терминал, в котором он запущен. Терминалы Windows используют кодовые страницы для отображения символов; кодовая страница по умолчанию - 437, но ее можно изменить с помощью команды chcp. chcp 65001
теоретически изменит кодовую страницу на utf-8, но насколько я знаю, python не знает, что с этим делать, так что вы СОЛНЕЧНО.
Похоже, что для выполнения этой работы необходимо изменить код подпроцесса для использования версии CreateProcess с расширенными символами (при условии, что она существует). Есть PEP, обсуждающий то же изменение, сделанное для файлового объекта на http://www.python.org/dev/peps/pep-0277/ Возможно, вы могли бы изучить вызовы Windows C и предложить подобное изменение. для подпроцесса.
Вы можете попробовать открыть файл как:
subprocess.call((n + f).encode("cp437"))
или любую другую кодовую страницу chcp
сообщает, что используется в окне командной строки. Если вы попытаетесь использовать chcp 65001
, как предлагал Старбак, вам придется отредактировать файл stdlib encodings \ aliases.py и заранее добавить cp65001
в качестве псевдонима к 'utf-8'.Это открытая проблема в исходном коде Python.
ОБНОВЛЕНИЕ: поскольку это сценарий с несколькими целевыми объектами, перед запуском такой команды убедитесь, что вы сначала запустите одну команду chcp
, проанализируйте вывод и получите текущую кодовую страницу командной строки (DOS). . Впоследствии используйте обнаруженную кодовую страницу для кодирования аргумента subprocess.call
.
Если ваш файл существует, вы можете использовать короткое имя файла (также известное как имя 8.3). Это имя определено для существующих файлов и не должно вызывать проблем для программ, не поддерживающих Unicode, когда передается в качестве аргумента.
Один из способов получить его (необходимо установить Pywin32 ):
import win32api
short_path = win32api.GetShortPathName(unicode_path)
В качестве альтернативы вы также можете использовать ctypes
:
import ctypes
import ctypes.wintypes
ctypes.windll.kernel32.GetShortPathNameW.argtypes = [
ctypes.wintypes.LPCWSTR, # lpszLongPath
ctypes.wintypes.LPWSTR, # lpszShortPath
ctypes.wintypes.DWORD # cchBuffer
]
ctypes.windll.kernel32.GetShortPathNameW.restype = ctypes.wintypes.DWORD
buf = ctypes.create_unicode_buffer(1024) # adjust buffer size, if necessary
ctypes.windll.kernel32.GetShortPathNameW(unicode_path, buf, len(buf))
short_path = buf.value