В этом кратком совете, взятом из книги «Useful Python», Стюарт рассматривает способы управления ОС Windows с помощью Python.
Реестр Windows
Windows полностью управляется из кода с помощью Win32 API, и Microsoft предоставляет обширную документацию в Microsoft Docs для всего, что Windows может делать программно. Все это также доступно из Python, хотя может показаться немного непонятным, если мы еще не привыкли к особому способу работы Win32 API. К счастью, существуют различные оболочки для этих низкоуровневых API, которые упрощают написание кода для программистов на Python.
Простой пример — взаимодействие с реестром Windows. Python фактически включает в себя модуль winreg для этого из коробки, поэтому дополнительная установка не требуется. Для примера давайте проверим, где Program Filesна самом деле находится папка:
>>> import winreg >>> hive = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) >>> key = winreg.OpenKey(hive, r"SOFTWARE\Microsoft\Windows\CurrentVersion") >>> value, type = winreg.QueryValueEx(key, "ProgramFilesDir") >>> value 'C:\\Program Files'
Необработанные строки
В приведенном выше коде мы используем «необработанные строки» для указания имени ключа:
r"SOFTWARE\Microsoft\Windows\CurrentVersion"
Строки, передаваемые Win32 API, часто содержат символ обратной косой черты ( \), поскольку Windows использует его в путях к файлам и путях реестра для отделения одного каталога от другого.
Однако Python использует обратную косую черту в качестве escape-символа, чтобы разрешить добавление в строку специальных нетипируемых символов. Например, строка Python «first line\nsecond line»— это строка с символом новой строки, поэтому текст распределяется по двум строкам. Это будет противоречить символу пути Windows: путь к файлу, который «C:\newdir\myfile.txt»интерпретируется \nкак новая строка.
Необработанные строки предотвращают это: префикс строки Python rудаляет особое значение обратной косой черты, так что это r»C:\newdir\myfile.txt«интерпретируется как задумано. Мы можем видеть, что обратная косая черта обрабатывается специальным образом значением, которое мы возвращаем для местоположения папки: оно печатается как — ’C:\\Program Files’с двойной обратной косой чертой, чтобы удалить ее особое значение — но это то, как Python печатает его, а не фактическое значение. Python мог бы напечатать это как r’C:\Program Files’вместо этого.
API Windows
Чтение реестра (и уж тем более запись в него) — источник тысячи взломов веб-страниц (многие из которых старые, на них не стоит ссылаться и используют древние ), но лучше реально использовать для этого API REGEDT32.EXE. (Раймонд Чен написал много длинных грустных историй о том, почему мы должны использовать API, а не реестр.) Как бы мы использовали Win32 API из Python, чтобы решить эту проблему?
Win32 Python API доступен в модуле PyWin32, который можно получить с помощью python -m pip install pywin32. Документация для модуля довольно скудна, но основная идея заключается в том , что большая часть API оболочки Windows (относящаяся к настройке ОС Windows) доступна в пакете win32com.shell. Чтобы узнать расположение Program Filesпапки, MSDN показывает, что нам нужна функция SHGetKnownFolderPath, которой передается константа KNOWNFOLDERID и флаг, установленный в 0. Константы оболочки доступны для Python в win32com.shell.shellcon(для «констант оболочки»), что означает, что для поиска Program Filesпапки требуется всего одна (по общему признанию сложная) строка:
>>> from win32com.shell import shell, shellcon >>> shell.SHGetKnownFolderPath(shellcon.FOLDERID_ProgramFiles, 0) "C:\\Program Files"
Копание в глубинах Win32 API дает нам доступ ко всему, к чему мы можем захотеть получить доступ в Windows (включая окна!), но, как мы видели, может быть довольно сложно выяснить, как делать то, что нам нужно, а затем перевести это на Python. К счастью, для многих часто используемых функций существуют библиотеки-оболочки. Одним из хороших примеров является PyGetWindow, который позволяет нам перечислять экранные окна и управлять ими. (Он заявлен как кроссплатформенный, но на самом деле работает только в Windows. Но это все, что нам нужно здесь.)
Мы можем установить PyGetWindow с помощью python -m pip install pygetwindow, а затем перечислить все окна на экране и манипулировать ими:
>>> import pygetwindow as gw >>> allMSEdgeWindows = gw.getWindowsWithTitle("edge") >>> allMSEdgeWindows [Win32Window(hWnd=197414), Win32Window(hWnd=524986)] >>> allMSEdgeWindows[0].title 'pywin32 · PyPI - Microsoft Edge' >>> allMSEdgeWindows[1].title 'Welcome to Python.org - Microsoft Edge'
Этими окнами можно управлять. Объект окна можно свернуть и восстановить, изменить его размер и переместить по экрану, а также сфокусировать и вывести на передний план:
>>> pythonEdgeWindow = allMSEdgeWindows[1] >>> pythonEdgeWindow.minimize() >>> pythonEdgeWindow.restore() >>> pythonEdgeWindow.size Size(width=1050, height=708) >>> pythonEdgeWindow.topleft Point(x=218, y=5) >>> pythonEdgeWindow.resizeTo(800, 600)
Всегда стоит искать в PyPI модули-оболочки, которые предоставляют более удобный API для всего, что мы пытаемся сделать с окнами или с Windows. Но при необходимости у нас есть доступ ко всему Win32 API от Python, и это позволит нам делать все, что мы можем придумать.