Вопрос
Кажется, что PyWin32 удобен тем, что в качестве возвращаемых значений передаются строки unicode с нулевым символом. Я хотел бы иметь дело с этими строками как "правильный".
Скажем, я получаю строку вроде: u'C:\\Users\\Guest\\MyFile.asy\x00\x00sy'
. Кажется, что это строка с нулевым символом C-стиля, которая висит в объекте юникода Python. Я хочу подрезать этого плохого мальчика до обычной последовательности символов, которые я мог бы, например, отобразить в строке заголовка окна.
Является ли обрезка строки в первом нулевом байте правильным способом справиться с ней?
Я не ожидал получить возвращаемое значение, подобное этому, поэтому я задаюсь вопросом, не хватает ли я чего-то важного в том, как Python, Win32 и Unicode играют вместе... или если это всего лишь ошибка PyWin32.
Фон
Я использую функцию выбора файлов Win32 GetOpenFileNameW
из пакета PyWin32. Согласно документации, эта функция возвращает кортеж, содержащий полный путь имени файла, как объект Unicode Python.
Когда я открываю диалог с существующим набором путей и файлов, я получаю странное возвращаемое значение.
Например, у меня был набор по умолчанию: C:\\Users\\Guest\\MyFileIsReallyReallyReallyAwesome.asy
В диалоговом окне я изменил имя на MyFile.asy
и нажал кнопку "Сохранить".
Полная часть пути возвращаемого значения: u'C:\Users\Guest\MyFile.asy\x00wesome.asy'`
Я ожидал, что это будет: u'C:\\Users\\Guest\\MyFile.asy'
Функция возвращает возвращенный буфер без обрезания завершающих байтов. Излишне говорить, что остальная часть моего кода не была настроена для обработки строки с нулевым завершением в стиле C.
Демо-код
Следующий код демонстрирует строку с нулевым завершением в возвращаемом значении из GetSaveFileNameW.
Направления: В диалоговом окне измените имя файла на "MyFile.asy", затем нажмите "Сохранить". Соблюдайте, что напечатано на консоли. Выход, который я получаю, равен u'C:\\Users\\Guest\\MyFile.asy\x00wesome.asy'
.
import win32gui, win32con
if __name__ == "__main__":
initial_dir = 'C:\\Users\\Guest'
initial_file = 'MyFileIsReallyReallyReallyAwesome.asy'
filter_string = 'All Files\0*.*\0'
(filename, customfilter, flags) = \
win32gui.GetSaveFileNameW(InitialDir=initial_dir,
Flags=win32con.OFN_EXPLORER, File=initial_file,
DefExt='txt', Title="Save As", Filter=filter_string,
FilterIndex=0)
print repr(filename)
Примечание. Если вы недостаточно сократите имя файла (например, если вы попробуете MyFileIsReally.asy), строка будет завершена без нулевого байта.
Окружающая среда
64-разрядный Windows 7 Professional (без пакета обновления), Python 2.7.1, PyWin32 Build 216
UPDATE: Артефакт Tracker PyWin32
Основываясь на комментариях и ответах, которые я получил до сих пор, это, вероятно, ошибка pywin32, поэтому я подал артефакт трекера.
ОБНОВЛЕНИЕ 2: Исправлено!
Марк Хэммонд сообщил в артефакте трекера, что это действительно ошибка. Исправление было проверено на rev f3fdaae5e93d, поэтому, надеюсь, это сделает следующий выпуск.
Я думаю, что Алекси Торхамо ответ ниже - лучшее решение для версий PyWin32 до исправления.