我正在创建一个python桌面应用程序,它将日志保存为Windows上用户的Documents文件夹中的.csv文件。该应用程序使用python 2.7和kivy 1.8.0编写,使用pyinstaller 2.1打包为Windows程序,安装程序使用Inno Setup Compiler。在这篇文章中,我将用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时崩溃,出现以下错误:
IOError: [Errno 2] No such file or directory: 'C:\\Users\\USER\\AppData\Roaming\\SPB_16.6\\Documents\\data_log.csv'
首先,为什么os.path.expanduser在某些系统上行为不端,而在其他系统上行为不正确?
其次,即使它在错误的目录中,open()也应该创建该文件(如果它不存在),那么为什么会导致它崩溃?
我已经弄明白是什么导致了这个问题。在大多数系统上,HOME为None,因此os.path.expanduser使用USERPROFILE。但是,在极少数情况下,HOME设置为C:\ SPB \或C:\ Users \ USER \ AppData \ Roaming \ SPB_16.6。我的解决方案是使用os.environ直接访问USERPROFILE,而不是使用os.path.expanduser。
答案 0 :(得分:1)
来自expanduser
的文档:
在Windows上,如果设置将使用HOME和USERPROFILE,否则使用a 将使用HOMEPATH和HOMEDRIVE的组合。初始〜用户 通过从创建的内容中剥离最后一个目录组件来处理 上面导出的用户路径。
如您所见,代码非常简单(使用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
本身可能出现的问题并不多。您需要检查程序中的那些环境变量,看它们是否包含正确的值。
import os
for var in ('HOME', 'USERPROFILE', 'HOMEPATH', 'HOMEDRIVE'):
print os.environ.get(var)
open
可能失败的一个可能原因是您尝试打开该文件的目录不存在,或者您无权访问该文件。