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

Posted

技术标签:

【中文标题】为啥 Tkinter 的 askdirectory() 在 Windows 上返回正斜杠?【英文标题】:Why does Tkinter's askdirectory() return forward slashes on Windows?为什么 Tkinter 的 askdirectory() 在 Windows 上返回正斜杠? 【发布时间】:2014-01-30 21:45:12 【问题描述】:

设置: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)

文件夹选择器不返回本机斜杠是否有原因?我用谷歌搜索并没有看到任何答案。

【问题讨论】:

python 正斜杠在 windows 中完全有效 @joaquin 直到它们与您的代码中的其他 os.path.join() 混合,对吧? 【参考方案1】:

编辑:

我将编辑我的答案,因为我认为我不是很清楚。


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

现在,似乎没有任何东西可以直接说明为什么askdirectory 是这样构建的。 Tkinter 一直以记录不善而著称。 ;)

不过,有几点需要考虑:

    \ 是 Python 字符串中的特殊字符。它创建一个escape sequence。因此,如果askdirectory 返回的路径包含反斜杠,则只能预期它会导致问题。或者,如果没有,您仍然需要一些安全代码来防止它们。

    Python 在路径中带有正斜杠的 Windows 和 *nix 系统上都可以正常工作。例如,这段代码:

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

    与此相同:

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

    唯一的区别是,使用第二种方法,您必须处理转义序列。我通过使用原始字符串来做到这一点,这在上面的链接中进行了解释。但是,只使用正斜杠要容易得多。

    因为 Tkinter 是跨平台的,所以在内部使用规范化路径结构既方便又高效。因此,为什么不使用在 Windows 和 *nix 系统上都可以使用而无需任何转义的那个呢?

    如果您必须为您的应用程序提供本地路径,Python 已经有内置函数来实现它。这些可以在os.path 模块中找到。

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

【讨论】:

您提供的原因有任何参考吗?如果不是,恕我直言,这不是答案。顺便提一句。更改斜杠更安全的方法是使用os.path.normpath 我有点想这是为了转义序列,但我觉得他们可能应该把它记录在某个地方,因为看起来我不知道如果最终用户要打开我在做什么我的配置文件。 @iCodez 当然,这不是无效的。但恕我直言,它没有抓住重点。问题是“为什么是 X”,你说:1)总是 X,2)关于 Python 中反斜杠的无关信息(反斜杠是特殊的事实并不禁止使用它们,也 - os.path 模块在 Windows 上使用反斜杠) 3) Python 使用斜杠和反斜杠的不相关信息 4) 不是背景问题的最佳解决方案(使用replace 而不是正确的工作工具 - os.path 模块)。也许对 OP 的问题没有答案——我也没有找到。 @Mgamerz:Tkinter 只是 tcl/tk 的一个薄包装。 askDirectory 调用 tcl/tk 命令 tk_chooseDirectory 如果你在 tk 源文件中查看 tk_chooseDirectory (tkWinDialog.c) 的实现,你会看到它在返回之前显式地将 \ 转换为 /。这是因为在内部 tcl/tk 总是对路径使用规范化的形式。它使编写跨平台应用程序更容易。 tcl 和 python 都提供了函数,当你真的需要本地路径名时,这些函数会返回特定于平台的路径形式。 -1: `\` 在 literal 字符串中是特殊的(在源代码中)。它在字符串对象内部(在内存中)并不特殊。 @Mgamerz:它不适用于转义序列。【参考方案2】:

Windows (NT) 实际上支持使用正斜杠定义的路径。 甚至可以有区分大小写的文件名。 请参阅 WinAPI CreateFile - FILE_FLAG_POSIX_SEMANTICS。它在 NTFS 上受支持。

http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx

【讨论】:

以上是关于为啥 Tkinter 的 askdirectory() 在 Windows 上返回正斜杠?的主要内容,如果未能解决你的问题,请参考以下文章

为什么tkinter.filedialog.askdirectory没有返回完整路径(使用选定的dirname)?

如何在 tkinter python 中的两个函数之间传递变量?

为啥我的 Tkinter 画布显示?

为啥 Tkinter 窗口打开这么慢?

如果在函数中创建,为啥 Tkinter 图像不显示?

如果在函数中创建,为啥 Tkinter 图像不显示?