Я предлагаю вам избегать хранения файлов и каталогов непосредственно в папке профиля пользователя (т. Е. Переменной среды UserProfile
) или домашней папке (т. Е. "%HomeDrive%%HomePath%"
). Это отличается от общепринятой практики в Unix для домашнего каталога (если мы игнорируем спецификацию базового каталога XDG), но в Редмонде действуйте так, как это делают Microsoft.
Создайте папку с уникальным именем для приложения в одном или нескольких из следующих расположений: локальная папка данных (для каждого пользователя), перемещаемая папка данных (для каждого пользователя) или папка данных программы (для каждого компьютера). Обратите внимание, что эти папки по умолчанию скрыты, поскольку обычно пользователи не имеют к ним прямого доступа.
Используйте локальную папку данных для кешей. Используйте перемещаемую папку данных для пользовательских данных и конфигурации с отслеживанием состояния. Используйте папку данных программы для данных и кешей, не относящихся к конкретному пользователю. Например, такая программа, как pip, может использовать папку данных программы для кэширования загруженных пакетов. (На практике pip кэширует пакеты для каждого пользователя, но в принципе он может кешировать для каждой машины.)
Если ваше приложение использует папку данных программы, убедитесь, что в этой папке всем пользователям разрешено добавлять и изменять подпапки и файлы. Если вы создаете папку лениво, вы можете добавить разрешения вручную. См. этот ответ для примера того, как изменить безопасность файла.
Переменные среды для локальных папок, папок с перемещаемыми данными и программных данных, соответственно, LocalAppData
, AppData
и ProgramData
. В Windows XP последний - "%AllUsersProfile%\Application Data"
, и, возможно, «Данные приложения» локализованы. Обычно вы не должны использовать эти переменные среды в приложении.
Поскольку большинство известных / специальных папок легко перемещать в проводнике, лучше всего запросить у оболочки текущий путь, вызвав SHGetFolderPath
или более новую функцию SHGetKnownFolderPath
вместо использования переменных среды и местоположений по умолчанию. Вы можете использовать ctypes для этого, если вам нужно оставаться в стандартной библиотеке Python. Но проще использовать PyWin32, который можно установить как пакет pypiwin32.
Вот несколько GUID известной папки для данных, документов и файлов мультимедиа:
User System
ProgramData FOLDERID_ProgramData
Local FOLDERID_LocalAppData
Roaming FOLDERID_RoamingAppData
Desktop FOLDERID_Desktop FOLDERID_PublicDesktop
Documents FOLDERID_Documents FOLDERID_PublicDocuments
Downloads FOLDERID_Downloads FOLDERID_PublicDownloads
Music FOLDERID_Music FOLDERID_PublicMusic
Pictures FOLDERID_Pictures FOLDERID_PublicPictures
Videos FOLDERID_Videos FOLDERID_PublicVideos
Вот соответствующие константы CSIDL
, за исключением того, что для «Загрузки» их нет:
User System
ProgramData CSIDL_COMMON_APPDATA
Local CSIDL_LOCAL_APPDATA
Roaming CSIDL_APPDATA
Desktop CSIDL_DESKTOP CSIDL_COMMON_DESKTOPDIRECTORY
Documents CSIDL_PERSONAL CSIDL_COMMON_DOCUMENTS
Music CSIDL_MYMUSIC CSIDL_COMMON_MUSIC
Pictures CSIDL_MYPICTURES CSIDL_COMMON_PICTURES
Videos CSIDL_MYVIDEO CSIDL_COMMON_VIDEO
SHGetKnownFolderPath
не является оболочкой PyWin32. У меня есть другой ответ, который вызывает его через ctypes. Кроме того, вы можете использовать PyWin32 для создания экземпляра KnownFolderManager
. Например:
import pythoncom
from win32com.shell import shell
kf_mgr = pythoncom.CoCreateInstance(shell.CLSID_KnownFolderManager, None,
pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IKnownFolderManager)
downloads_path = kf_mgr.GetFolder(shell.FOLDERID_Downloads).GetPath()
Или вызовите унаследованную функцию SHGetFolderPath
с константой CSIDL
. Например:
from win32com.shell import shell, shellcon
SHGFP_TYPE_CURRENT = 0
SHGFP_TYPE_DEFAULT = 1
local_data_path = shell.SHGetFolderPath(None, shellcon.CSIDL_LOCAL_APPDATA,
None, SHGFP_TYPE_CURRENT)
person
Eryk Sun
schedule
24.09.2017