【问题标题】:Finding the user's "My Documents" path查找用户的“我的文档”路径
【发布时间】:2011-06-03 13:18:33
【问题描述】:

我有这个小程序,它需要在他们的“我的文档”文件夹中创建一个小的 .txt 文件。这是我的代码:

textfile=open('C:\Users\MYNAME\Documents','w')
lines=['stuff goes here']
textfile.writelines(lines)
textfile.close()

问题是如果其他人使用它,我如何将MYNAME更改为他们的帐户名?

【问题讨论】:

    标签: python


    【解决方案1】:

    使用os.path.expanduser(path),见http://docs.python.org/library/os.path.html

    例如expanduser('~/filename')

    根据文档,这适用于 Unix 和 Windows。

    编辑:由于 Sven 的评论,正斜杠。

    【讨论】:

    • 最好在路径中使用正斜杠:'~/filename'。否则,您将得到像 '~\name' 这样的意外结果,其中 \n 将被换行符替换。
    • @Sven - 我不确定。我不使用 Windows,不确定 Python 如何处理 Windows 路径分隔符。
    • 在 Windows 上,os.path.expanduser('~/filename') 调用会产生类似于 'C:\\Documents and Settings\\<username>/filename' 的结果,这不是用户的 My Documents 文件夹中的某些内容的路径。
    • 请注意,如果用户移动了他们的“我的文档”文件夹以使其不再位于~ 下(例如,如果它位于网络共享上,则此不起作用或不同的驱动器)。
    • 这不起作用。你需要的是df = shell.SHGetDesktopFolder() pidl = df.ParseDisplayName(0, None, "::{450d8fba-ad25-11d0-98a8-0800361b1103}")[1] mydocs = shell.SHGetPathFromIDList(pidl)
    【解决方案2】:

    这无需任何额外的库即可工作:

    import ctypes.wintypes
    CSIDL_PERSONAL = 5       # My Documents
    SHGFP_TYPE_CURRENT = 0   # Get current, not default value
    
    buf= ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
    ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf)
    
    print(buf.value)
    

    如果用户更改了文档位置和/或默认保存位置,也可以使用。

    【讨论】:

    • 这个答案与stackoverflow.com/a/3859336/1543290 非常相似 - 但是他们定义了SHGFP_TYPE_CURRENT= 0 # Want current, not default value 而不是这个答案的SHGFP_TYPE_CURRENT = 1 # Get current, not default value!哪个是真的?根据stackoverflow.com/a/23852297/1543290 看来0 是正确的
    • @Zvika 这不是对或错。这取决于你需要什么。如果需要当前值,则使用 1,如果默认,则使用 0。如果用户更改了位置,那么显然当前值更重要。
    • 我想使用current 而不是default value 哪个值适合这个?根据这个答案的代码注释-1,根据另一个答案-0
    • 使用shell32 = ctypes.OleDLL('shell32')。使用 windll (1) 不会检查 HRESULT 代码,并且 (2) 让您任由为 restypeargtypeserrcheckwindll.shell32.SHGetFolderPathW 设置的任何库所摆布。 cdllwindlloledll 加载器的整个想法从一开始就很糟糕。
    • @EspoirMurhabazi 不确定你的意思。
    【解决方案3】:

    在 Windows 上,您可以使用类似于问题已接受答案中所示的内容:Python, get windows special folders for currently logged-in user

    对于My Documents 文件夹路径,在shell.SHGetFolderPath() 函数调用中使用shellcon.CSIDL_PERSONAL 而不是shellcon.CSIDL_MYPICTURES

    因此,假设您安装了 PyWin32 扩展1,这可能可以工作(请参阅下面更新部分的警告):

    >>> from win32com.shell import shell, shellcon
    >>> shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
    u'<path\\to\\folder>'
    

    更新:我刚刚读到something 说如果用户更改了 Win7 文档库中的默认保存文件夹,CSIDL_PERSONAL 将不会返回正确的文件夹。这是指您可以在库的“属性”对话框中执行的操作:


    勾选表示路径设置为默认保存位置。

    我目前不知道通过 PyWin32 调用 SHLoadLibraryFromKnownFolder() 函数的方法(目前没有 shell.SHLoadLibraryFromKnownFolder。但是应该可以使用 ctypes 模块来实现。

    1最新版本的 Python for Windows Extensions 安装程序目前可从以下地址获得:http://sourceforge.net/projects/pywin32

    【讨论】:

      【解决方案4】:

      在 Linux(Ubuntu 18.04.5) 和 Window 7 上测试

      import os
      os.path.expanduser('~/Documents')
      

      【讨论】:

      • 这与accepted answer有何不同?
      • 这在 Linux 和 macOS 上可能没问题,但在许多情况下在 Windows 上会给出错误的结果。
      【解决方案5】:

      您可以使用 pywin32 扩展来访问 Win32 API。通过使用 Win32 API,您可以获得代表“我的文档”桌面项的虚拟文件夹。

      from win32com.shell import shell, shellcon
      doc_folder = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
      

      您可以在此处找到 CSIDL_PERSONAL 的描述: https://docs.microsoft.com/en-us/windows/win32/shell/csidl

      【讨论】:

      • 不鼓励使用纯代码的答案。请单击edit 并添加一些词来总结您的代码如何解决问题,或者解释您的答案与之前的答案/答案有何不同。 From Review
      • 欢迎来到 StackOverflow!在发布之前,请确保您的解决方案尚未发布为 another answer
      【解决方案6】:

      对于 Windows,这可行

      document_path = os.path.expanduser('~\Documents')
      

      返回准备编码的正确路径: 例如

      someExcel_to_process =  pd.ExcelFile(document_path+'\\SomeExcel.xlsx')
      

      【讨论】:

        猜你喜欢
        • 2011-01-25
        • 1970-01-01
        • 2012-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多