为啥 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)?