简体   繁体   English

os.path.exists()在Windows上的%appdata%中给出误报

[英]os.path.exists() gives false positives in %appdata% on Windows

I'm trying to make my game project not save in its own directory like it's 1995 or something. 我正在努力让我的游戏项目不能像1995年那样保存在自己的目录中。

The standard library isn't cooperating. 标准库不合作。

Basically, I'm trying to save in %appdata%\\MYGAMENAME\\ (this is the value of _savedir on win32.) open() will become understandably upset if such a folder does not exist, so I use os.path.exists() to check if it does indeed exist and create it if it does not. 基本上,我正在尝试保存%appdata%\\MYGAMENAME\\ (这是win32上_savedir的值。)如果这样的文件夹不存在, open()会变得可以理解,所以我使用os.path.exists()检查它是否确实存在,如果不存在则创建它。

Trouble is, os.path.exists() returns True, but I can look in the folder and confirm that it does not. 麻烦的是, os.path.exists()返回True,但我可以查看该文件夹并确认它没有。 It also doesn't return True if I try it in the REPL; 如果我在REPL中尝试它也不会返回True; only here (I've confirmed with my debugger that it does). 只有在这里(我已经确认我的调试器确实如此)。

The pickling step appears to proceed properly; 酸洗步骤似乎正常进行; it jumps to the else: clause immediately after. 它会立即跳转到else:子句。 But I can confirm with the OS filesystem browser and the REPL that neither folder nor file exist! 但我可以通过OS文件系统浏览器和REPL确认文件夹和文件都不存在!

Here's the full function source (don't laugh!): 这是完整的功能源(不要笑!):

def save(self):
        "Save the game."
        #Eh, ____ it, just pickle gamestate. What could go wrong?
        save_path=os.path.join(_savedir,"save.sav")
        temporary_save_path=os.path.join(_savedir,"new_save.sav")
        #Basically, we save to a temporary save, then if we succeed we copy it over the old one.
        #If anything goes wrong, we just give up and the old save is untouched. Either way we delete the temp save.
        if not os.path.exists(_savedir):
            print("Creating",_savedir)
            os.makedirs(_savedir)
        else:
            print(_savedir,"exists!")
        try:
            pickle.dump(self,open(temporary_save_path,"wb"),protocol=pickle.HIGHEST_PROTOCOL)
        except Exception as e:
            print("Save failed: {0}".format(e))
            print("The game can continue, and your previous save is still intact.")
        else:
            shutil.move(temporary_save_path,save_path)
        finally:
            try:
                os.remove(temporary_save_path)
            except Exception:
                pass

(Yeah, catching Exception is usually inadvisable, but I want things to fail gracefully if ANYTHING goes wrong, there's no case where an actual exception would come up there and I'd want to do anything else.) (是的,捕捉Exception通常是不可取的,但是如果出现任何问题,我希望事情能够优雅地失败,不存在实际异常会出现的情况,我想做其他任何事情。)

What could be the issue here? 这可能是什么问题?

Python does not expand the value of %appdata% . Python不会扩展%appdata%的值。 Instead, a literal directory is created relative to the current working directory. 而是相对于当前工作目录创建文字目录。 Run print(os.path.abspath(_savedir)) , that is where the file is created and exists. 运行print(os.path.abspath(_savedir)) ,即创建和存在文件的位置。

Use os.environ['APPDATA'] to create an absolute path to the application data directory: 使用os.environ['APPDATA']创建应用程序数据目录的绝对路径:

_savedir = os.path.join(os.environ['APPDATA'], 'MYGAMENAME')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM