为什么Tkinter的askdirectory()在Windows上返回正斜杠?

8
安装:Windows 7
Python版本:3.3
我正在制作一个跨平台应用程序,并使用Tkinter的tkinter.filedalog.askdirectory模块中的askdirectory()方法让用户提供目录。这个方法很好用,但是在Windows系统中它给出了正斜杠而不是反斜杠。
Windows使用反斜杠而不是正斜杠,所以当我尝试保存一个带有本地文件斜杠的文本文件(配置文件存储目录,因此需要添加末尾斜杠),它看起来很奇怪:
F:/Pictures/Wallpapers\

我用来添加本机斜杠的代码只是 os.sep,它是当前系统的本机目录分隔符,在*nix和windows上不同。

    def getDownloadPath(self):
       pathdir=askdirectory()
       if pathdir=='':
           return #cancel
       pathdir+=os.sep
       self.download_location.delete(0,END)
       self.download_location.insert(0,pathdir)

为什么文件夹选择器不返回本机斜杠?我搜索了一下,没有找到答案。


1
Python在Windows中使用正斜杠是完全有效的。 - joaquin
直到它们与您代码中的其他 os.path.join() 混合在一起,对吗? - Shayan
2个回答

3

编辑:

我要修改我的答案,因为我觉得我没有表述清楚。


首先,tkinter.filedialog.askdirectory始终在返回的路径中使用正斜杠。所以,你看到的不是一个错误——而是函数设计的结果。此外,这种行为在Windows和*nix系统上都会发生。

现在,似乎没有什么直接说明为什么askdirectory以这种方式构建的。Tkinter一直以来就有文档不全的声誉。 ;)

然而,有几件事值得考虑:

  1. \ is a special character in Python strings. It creates an escape sequence. Thus, if the path returned by askdirectory contained backslashes, it is only expected that it would cause problems. Or, if it didn't, you would still need some safety code to prevent them.

  2. Python works just fine on both Windows and *nix systems with forwardslashes in paths. As an example, this code:

    open("C:/path/path/")
    

    works identically to this:

    open(r"C:\path\path")
    

    The only difference is, with the second method, you have to handle escape sequences. I did this by using a raw-string, which is explained in the link above. However, it is a lot easier to just use forwardslashes.

  3. Because Tkinter is cross-platform, it is both convenient and efficient to use a normalized path construct internally. Therefore, why not use the one that works on both Windows and *nix systems without any escaping necessary?

  4. If you must have a native path for your application, Python already has built-in functions to make it. These can be found in the os.path module.

考虑到这些原因,使用正斜杠构建askdirectory似乎是合乎逻辑的。


2
你有提供任何理由的参考资料吗?如果没有,那么我认为这不是一个答案。顺便说一下,更安全的更改斜杠的方法是使用 os.path.normpath - BartoszKP
我有点猜到它是用于转义序列,但我觉得他们也许应该在某个地方记录下来,因为如果最终用户打开我的配置文件,看起来好像我不知道在做什么。 - Mgamerz
1
@iCodez 嗯,它不是void,当然。但在我看来,它错过了重点。问题是“为什么X”,而你说:1)总是X,2)关于Python中反斜杠的无关信息(反斜杠是特殊字符并不意味着不能使用它们,此外 - os.path模块在Windows上使用反斜杠),3)与Python使用斜杠和反斜杠无关的信息,4)解决背景问题的不是最佳方案(使用replace而不是适合工作的正确工具 - os.path模块)。也许OP的问题只是没有答案 - 我也没有找到答案。 - BartoszKP
1
@Mgamerz:Tkinter只是tcl/tk的一个薄包装。askDirectory调用了tcl/tk命令tk_chooseDirectory。如果你查看tk_chooseDirectory(tkWinDialog.c)的实现,你会发现它在返回之前明确地将\转换为/。这是因为内部tcl/tk总是使用路径的规范形式,这使得编写跨平台应用程序更容易。tcl和python都提供了函数,用于返回特定于平台的路径形式,以便在真正需要本机路径名时使用。 - Bryan Oakley
1
-1: \\文字字符串(源代码中)内是特殊的。在字符串对象(内存中)中则不是特殊的。@Mgamerz:它不是用于转义序列。 - jfs
显示剩余2条评论

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接