从Python中的一小组可能的文件名中确定正确文件名的好方法

从Python中的一小组可能的文件名中确定正确文件名的好方法,python,Python,我有一个用于GUI的python项目,用于计算集群中的slurm队列管理器。我可以做的一件事是在文本窗口中打印特定作业的特定文件的内容 但是,人们对同一类型文件使用的扩展名有时会发生变化。我可以对它进行编程,使其适合我,但我也希望能够查找其他人的文件 我解决这个问题的方法如下 extensions = [".ex1", ".ext2", "ext3"] for ext in extensions: try: f = open(jobname+ext), "r")

我有一个用于GUI的python项目,用于计算集群中的slurm队列管理器。我可以做的一件事是在文本窗口中打印特定作业的特定文件的内容

但是,人们对同一类型文件使用的扩展名有时会发生变化。我可以对它进行编程,使其适合我,但我也希望能够查找其他人的文件

我解决这个问题的方法如下

extensions = [".ex1", ".ext2", "ext3"]
for ext in extensions:
    try:
        f = open(jobname+ext), "r")
        content = f.read()
        f.close()

        <doing some stuff with content>

    except IOError:
        if ext == extensions[-1]:
            print("File not found")
            return
extensions=[“.ex1”、“.ext2”、“ext3”]
对于ext-in扩展:
尝试:
f=打开(作业名+外部),“r”)
content=f.read()
f、 关闭()
除IOError外:
如果ext==扩展[-1]:
打印(“未找到文件”)
返回
如果实际使用的扩展名包含在扩展名中,那么我的代码会找到它。我想知道更有经验的程序员是否有更好/更优雅/更高效的方法。幸运的是,要读取的文件非常小,因此循环所有的可能性不会花费太多时间。但是这种特殊的解决方案可能不适用于其他情况。

您可以使用该语句打开一个文件,然后让它自动关闭。此外,您可以省略
open()
(默认为
'r'
)的模式参数,并可能在找到有效扩展名后添加
中断

extensions = [".ex1", ".ext2", "ext3"]
for ext in extensions:
    try:
        with open(jobname+ext)) as f:
            content = f.read()            

        # do some stuff with content
        break    
    except IOError:
        if ext == extensions[-1]:
            print("File not found")
            return

据我所知,您已经知道文件名和路径,只有扩展名是未知的。 使用
glob
包查找具有该名称的所有文件,如下所示:

from glob import glob

matches = glob("/path/to/files/knownfilename.*")
if not matches:
    print("File not found!")
    return
try:
    with open(matches[0], "r") as f:
        content = f.read()
    # do stuff
except IOError:
    print("Error reading file {}".format(matches[0]))
在这种情况下,您可能必须处理以下可能性:

  • 有多个文件具有该名称和不同的扩展名
  • matches
    列表中的第一个文件不是您想要的文件类型(可能是扩展名为.bak的备份文件或其他文件),因此您可能还想将一些扩展名列入黑名单

您可以使用
os.listdir('.')
获取当前工作目录中的文件名列表,使用
for
循环遍历该列表,然后从
jobname
的长度中切片文件名,并使用
in
操作符测试它是否是
扩展名
列表/元组中的扩展名之一<当找到具有所需名称的文件时,处理该文件后,代码>中断。如果循环完成而未中断,则使用
for
循环的
else
块打印
文件未找到
消息:

import os
extensions = '.ext1', '.ext2', '.ext3'
for filename in os.listdir('.'):
    if filename.startswith(jobname) and filename[len(jobname):] in extensions:
        with open(filename) as f:
            content = f.read()
            # doing some stuff with content
        break
else:
    print("File not found")

即使这样做有效,将当前扩展与列表末尾进行比较的逻辑也会让人感到奇怪。在最坏的情况下,如果最后一个扩展名意外地复制到列表的前面,这将导致难以诊断的错误

由于(可能)您已经在找到文件后立即从循环中返回,因此您可以将“缺少的文件”行为放在循环之后(只有在没有找到文件的情况下才会到达),并将catch块留空:

extensions = [".ex1", ".ext2", ".ext3"]
for ext in extensions:
    try:
        with open(jobname+ext), "r") as f:
            content = f.read()

            <doing some stuff with content>

            return

    except IOError:
        pass

print("File not found")
extensions=[“.ex1”、“.ext2”、“.ext3”]
对于ext-in扩展:
尝试:
以open(作业名+外部代码),“r”作为f:
content=f.read()
返回
除IOError外:
通过
打印(“未找到文件”)

您可以考虑删除和张贴,因为堆栈溢出更适合不工作的代码,而不是关于工作代码的最佳实践和优化的问题。为什么用户不能将文件扩展名与文件名一起输入?或者,您可以使用
glob
包查找具有此名称的所有文件(不考虑扩展名,如somefilename.*),并尝试读取找到的文件。虽然这两点都是正确的,但主要问题没有得到解决。该函数仍将仅查找具有预定义扩展名的文件。请注意,这将迭代目录中的每个文件,而不是检查是否存在多个可能的文件之一。在有很多文件的目录中,速度会慢得多。