为什么 os.path.expanduser 不返回主目录? [英] Why is os.path.expanduser not returning the home directory?

查看:113
本文介绍了为什么 os.path.expanduser 不返回主目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个 python 桌面应用程序,它将日志保存为 Windows 上用户的 Documents 文件夹中的 .csv 文件.该应用程序使用 python 2.7 和 kivy 1.8.0 编写,使用 pyinstaller 2.1 打包为 Windows 程序,安装程序使用 Inno Setup Compiler 制作.在这篇文章中,我会将用户的真实姓名替换为 USER.

I am making a python desktop application that saves a log as a .csv file in the user's Documents folder on Windows. The application is written in python 2.7 and kivy 1.8.0, packaged as a Windows program using pyinstaller 2.1, and the installer is made using Inno Setup Compiler. In this post, I will replace the user's real name with USER.

我有以下几行代码:

DOCUMENTS = os.path.expanduser('~\\Documents\\')
print DOCUMENTS
with open(DOCUMENTS + 'data_log.csv', 'ab') as f:
    do stuff

在我的电脑和我测试过的另一台电脑上,程序按预期运行.DOCUMENTS 评估为C:\Users\USER\Documents\".但是,在我尝试过的其他三台计算机上,DOCUMENTS 评估为C:\Users\USER\AppData\Roaming\SPB_16.6\Documents\".然后程序在尝试创建 data_log.csv 时崩溃,给出以下错误:

On my computer and one other I've tested it on, the program works as expected. DOCUMENTS evaluates to 'C:\Users\USER\Documents\'. However, on the three other computers I've tried, DOCUMENTS evaluates to 'C:\Users\USER\AppData\Roaming\SPB_16.6\Documents\'. The program then crashes when it tries to create data_log.csv, giving the following error:

IOError: [Errno 2] No such file or directory: 'C:\\Users\\USER\\AppData\Roaming\\SPB_16.6\\Documents\\data_log.csv'

首先,为什么 os.path.expanduser 可能在某些系统上行为不当,而在其他系统上却没有?

First, why might os.path.expanduser misbehave on certain systems, but not on others?

其次,即使它在错误的目录中,如果文件不存在,open() 应该创建该文件,那为什么会导致它崩溃?

我已经弄清楚是什么导致了这个问题.在大多数系统上,HOME 为 None,因此 os.path.expanduser 使用 USERPROFILE.但是,在极少数情况下,HOME 设置为 C:\SPB\ 或 C:\Users\USER\AppData\Roaming\SPB_16.6 之类的内容.我的解决方案是使用os.environ直接访问USERPROFILE,而不是使用os.path.expanduser.

I've figured out what's causing this problem. On most systems, HOME is None, so os.path.expanduser uses USERPROFILE instead. However, in rare cases HOME is set to something like C:\SPB\ or C:\Users\USER\AppData\Roaming\SPB_16.6. My solution is to use os.environ to access USERPROFILE directly instead of using os.path.expanduser.

推荐答案

来自expanduser的文档:

在 Windows 上,如果设置了 HOME 和 USERPROFILE 将被使用,否则将使用将使用 HOMEPATH 和 HOMEDRIVE 的组合.初始~用户通过从创建的目录中剥离最后一个目录组件来处理上面派生的用户路径.

On Windows, HOME and USERPROFILE will be used if set, otherwise a combination of HOMEPATH and HOMEDRIVE will be used. An initial ~user is handled by stripping the last directory component from the created user path derived above.

如你所见,代码非常简单(用inspect转储):

As you can see, the code is extremely simple (dumped with inspect):

def expanduser(path):
    """Expand ~ and ~user constructs.

    If user or $HOME is unknown, do nothing."""
    if path[:1] != '~':
        return path
    i, n = 1, len(path)
    while i < n and path[i] not in '/\\':
        i = i + 1

    if 'HOME' in os.environ:
        userhome = os.environ['HOME']
    elif 'USERPROFILE' in os.environ:
        userhome = os.environ['USERPROFILE']
    elif not 'HOMEPATH' in os.environ:
        return path
    else:
        try:
            drive = os.environ['HOMEDRIVE']
        except KeyError:
            drive = ''
        userhome = join(drive, os.environ['HOMEPATH'])

    if i != 1: #~user
        userhome = join(dirname(userhome), path[1:i])

    return userhome + path[i:]

expanduser 本身不会出错.您需要检查程序中的这些环境变量,看看它们是否包含正确的值.

There's not much that can go wrong with expanduser itself. You'll want to check those environment variables inside your program to see if they hold the correct values.

    import os
    for var in ('HOME', 'USERPROFILE', 'HOMEPATH', 'HOMEDRIVE'):
        print os.environ.get(var)

open 失败的一个可能原因是您尝试打开文件的目录不存在,或者您没有访问它的权限.

A likely reason open may be failing is that the directory where you're trying to open the file doesn't exist, or you don't have permissions to access it.

这篇关于为什么 os.path.expanduser 不返回主目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆