解析 askopenfilenames() 的结果?
Posted
技术标签:
【中文标题】解析 askopenfilenames() 的结果?【英文标题】:Parsing the results of askopenfilenames()? 【发布时间】:2011-05-06 04:47:58 【问题描述】:我正在尝试从 Python 3.2 中的 tkinter.filedialog.askopenfilenames() 获取文件名列表。
files = askopenfilenames(initialdir="C:\\Users\\BVCAP\\Videos", title="Select files")
self.num_files.set(len(files))
我期望输出是一个元组(或者可能是一个列表),每个元素都包含一个文件名。据我所知,它返回一个字符串,其中每个元素都包含在花括号 中,如下所示:
C:\Users\BVCAP\File1.txt C:\Users\BVCAP\File2.txt
如果我尝试打印(文件),这就是我得到的。它看起来像某种列表的格式,但它似乎只是一个字符串。是我做错了什么,还是这个函数的输出实际上是一个格式化为文件列表的字符串,我需要自己拆分。
【问题讨论】:
哎呀!如果文件名中有大括号(
或
),您会得到什么?
@Gabe:如果发生这种情况,我会亲自勒死在文件名中放大括号的人。
【参考方案1】:
今天实现这个方法时,askopenfilenames
返回一个包含所有选择文件的元组,不再是带有花括号的奇怪字符串(必须已修复)。
奇怪的是,如果按下取消按钮或用户退出浏览窗口,则会返回一个空字符串而不是空列表或元组。幸运的是,Python 将字符串识别为可迭代对象,这意味着您仍然可以检查 len(filedialog.askopenfilenames()) == 0
是否。
【讨论】:
【参考方案2】:我在查找为什么我得到大括号而不是正确的列表时发现了这个问题。
这是我的解决方法:
file_list=[]
files = files = askopenfilenames(initialdir="C:\\Users\\BVCAP\\Videos", title="Select files")
for file in files:
file_list.append(file)
我注意到当我在我的方法中使用askopenfilenames
时,我从未查看过返回的对象。我把它当作一个元组,它工作得很好。所以知道它可以在 for 循环中迭代,将每个项目附加到一个新的空白列表中是有意义的。
我希望这对遇到此错误的其他人有所帮助。
【讨论】:
【参考方案3】:我支持 Eldererathis 的回答,这是我为 Linux、Mac OS X 和 Windows 下的 Python 版本 2.X(主要是 2.5 及更高版本)版本找到的最佳解决方案。 When a tkFileDialog
calls the askopenfilename(...,multiple=1)
methods with argument multiple=1
, I could not get it work properly under Windows (Linux and Mac OS X were fine) when a single file was selected (the file is processed as a @987654324 @ 而不是 'tuple'
)。
我尝试了 Paul 在 cmets 中建议的 files = re.findall('\(.*?)\', files
,但它并没有改变任何东西。我也尝试过files = tuple(files)
和files = list(files)
,但就我所见,这不是一个可行的解决方法。
到目前为止,files = tkRoot.master.splitlist(files)
在我测试过的所有环境(Win32、Win64、Linux32、Linux64、Mac OS X)下都能正常工作。
【讨论】:
【参考方案4】:这实际上是自 Python 2.6 发行版以来一直存在的 Windows 版本上的错误。你可以找到问题on their tracker,并且在 cmets 中有一个解决方法(我没有亲自尝试过这个解决方法,因为我在 Linux 上,它返回一个正确的元组)。从那以后我不知道有任何修复,并且该问题尚未标记为已关闭/已解决。
评论中建议的解决方法基本上是这样做:
master = Tk()
files = askopenfilenames(initialdir="C:\\Users\\BVCAP\\Videos", title="Select files")
files = master.tk.splitlist(files) #Possible workaround
self.num_files.set(len(files))
【讨论】:
谢谢,很高兴知道。该解决方法实际上并没有起作用,但是一旦我知道它是具有该格式的字符串,将其转换为列表就不是问题了。 HI 改用了这个:files = re.findall('\(.*?)\', files) FWIW,该错误仍在 Python 2.7.3 中,@Paul 使用re
的解决方法可能是最简单的解决方法,尽管您可能希望以 askopenfilenames()
是否返回其他内容为条件tuple
以防万一它得到修复。
另一个错误显然是一次可以选择的文件数量有限制——我已经使用 Python 2.7.5 进行了验证。见问题Quantity limitation for dialog window selecting files or for keys in a dictionary?。
这应该已在 2.7.7 中修复。见bugs.python.org/issue19020 和bugs.python.org/issue5712。【参考方案5】:
我没有给你一个确切的答案,因为我仍然停留在 Python 2.x 中,但在我的世界里 askopenfilenames 返回一个元组,所以我怀疑它会在 3.x 中发生很大变化。也许尝试投射为列表:
filelist = list(files)
或者通过迭代使用列表推导:
filelist = [file for file in files]
【讨论】:
以上是关于解析 askopenfilenames() 的结果?的主要内容,如果未能解决你的问题,请参考以下文章