NamedTemporaryFile存在,但外部程序无法访问i

2024-06-17 07:57:29 发布

您现在位置:Python中文网/ 问答频道 /正文

这是this question关于使用NamedTemporaryFile()的后续排序

我有一个函数可以创建并写入一个临时文件。然后我想在另一个函数中使用该文件,该函数调用使用该文件的终端命令(该程序来自Blast+suite,blastn)。在

def db_cds_to_fna(collection="genes"):  # collection gets data from mongoDB

    tmp_file = NamedTemporaryFile()
    # write stuff to file

    return tmp_file

def blast_all(blast_db, collection="genes"):        

    tmp_results = NamedTemporaryFile()    
    db_fna = db_cds_to_fna(collection) # should return another file object

    Popen(
        ['blastn',
         '-query', db_fna.name,
         '-db', blast_db,
         '-out', tmp_results.name,
         '-outfmt', '5']  # xml output
    )

    return tmp_results

当我调用blast_all时,我从blastn命令得到一个错误:

^{pr2}$

但是,就在Popen调用之前,如果我执行os.path.isfile(db_fna.name),它的计算结果是True。我也可以

print Popen(['head', db_fna.name]).communicate(0)

它正确地输出了文件的第一行。所以文件存在,而且是可读的。此外,我使用相同的策略从同一blast+套件调用不同的程序(makeblastdb,请参阅顶部链接的问题),这样就可以工作了。权限可能有问题吗?如果文件不存在,FWIWblastn将返回相同的错误,但很明显,我创建的文件是正确的,并且当我调用Popen时,它是可读的,所以我被难住了。在


Tags: 文件to函数namedbreturnresultstmp
2条回答

我也有过类似的问题。我找了很久,以为永远找不到原因。在

在我的例子中,问题是由于文件系统延迟造成的。我想我最后使用time.sleep进行了一次肮脏的攻击,在开始在子进程中访问临时文件之前,给文件系统一些时间来创建临时文件。在

希望有帮助!在

我想我找到了导致这种行为的原因。首先,Popen()函数通常不会等到外部命令完成后再继续处理它。第二,因为正如用户glibdud在我的另一个问题中提到的in his answerNamedTemporaryFile的作用与{a2}相似

It will be destroyed as soon as it is closed (including an implicit close when the object is garbage collected).

由于我的blast_all()函数的结尾不返回query临时文件,因此在运行外部blastn命令时,该文件将被关闭并被垃圾回收,因此该文件被删除。我猜外部head命令执行得很快,不会遇到这个问题,但是blastn可能需要几分钟才能运行。在

因此,解决方案是强制Popen()等待:

Popen(
    ['blastn',
     '-query', db_fna.name,
     '-db', blast_db,
     '-out', tmp_results.name,
     '-outfmt', '5']  # xml output
).wait()

相关问题 更多 >