函数中的 Subprocess.call() 不会暂停调用该函数的脚本

2024-01-13

我寻找并找到了解决方案,尝试了它们并得到了相同的结果。我尝试使用Popen.wait(), run() and call()。根据其他用户的建议,我还尝试将命令作为字符串列表传递。没用。子进程调用不会给出错误,所以这不是问题。

这是函数:

def blast(file):
    command = f'blastn -query {output_path}fasta_files/{file} -db {db_path} -max_hsps 1 -max_target_seqs 40 -num_threads 4 -evalue 1e-5 ' \
              f'-out {output_path}blast/{file[:-2]}txt -outfmt "6 qseqid sseqid pident staxids sskingdoms qstart qend ' \
              f'qlen length sstart send slen evalue mismatch gapopen bitscore stitle"'
    subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).wait()

这是对该函数的调用:

import blastn
from process_blast_output import *
from remove_false_sequences import *
import os

directory = '/some/path/'


if __name__ == '__main__':
    for file in os.listdir(directory + 'fasta_files'):
        if 'btcaA1_trimmed' in file:
            blastn.blast(f'{file}') # That's where the function is called
            dataframe = get_dataframe(directory + f'blast/{file[:-2]}txt')
            dataframe = get_taxonomic_data(dataframe)
            delete_false_hits(fasta_to_dictionary(dataframe), directory + f'fasta_files/{file[:-2]}fa')

我没有传递字符串,而是尝试传递列表:

subprocess.Popen(['blastn', '-query', f'{output_path}fasta_files/{file}', '-db', f'{db_path}', '-max_hsps', '1',
                  '-max_target_seqs', '40', '-num_threads', '4', '-evalue', '1e-5', '-out',
                  f'{output_path}blast/{file[:-2]}txt', '-outfmt', "6 qseqid sseqid pident staxids sskingdoms "
                                                                   "qstart qend qlen length sstart send slen evalue"
                                                                   " mismatch gapopen bitscore stitle"],
                 stdout=subprocess.PIPE).wait()

可能实际的问题是你正在设置stdout=subprocess.PIPE但随后忽略输出。如果您想丢弃任何输出,请使用stdout=subprocess.DEVNULL;如果你想让子进程正常写入标准输出,就不要设置stdout at all.

无论你使用shell=True(第一个参数由 shell 解析的单个字符串组成)或不(在这种情况下,第一个参数应该是正确标记化的字符串列表)与是否等待子进程无关。

您通常应该避免Popen,默认情况下不等待。subprocess.run()及其遗产表亲check_call()等人。等待外部子进程。

一般来说,可能会避免shell=True如果可以的话。

def blast(file):
    subprocess.run(
        ['blastn', '-query,' f'{output_path}fasta_files/{file}',
          '-db', db_path, '-max_hsps', '1', '-max_target_seqs', '40',
          '-num_threads', '4', '-evalue', '1e-5 ',
          '-out', f'{output_path}blast/{file[:-2]}txt',
          '-outfmt' "6 qseqid sseqid pident staxids sskingdoms qstart qend "
                    "qlen length sstart send slen evalue mismatch gapopen "
                    "bitscore stitle"],
    stdout=subprocess.DEVNULL, check=True)

您创建的子进程将被等待,但当然它仍然有可能创建自己的独立子进程,如果子进程向调用者隐藏了这一点,Python 就无法直接等待。

顺便说一句,你的if __name__ == '__main__'代码应该很简单;如果您将所有有用的代码都放在该块中,则该文件将无法用于import无论如何,进入另一个脚本,所以整个__name__检查是没有意义的。这样做的目的是让你可以说

def useful_code():
    # lots of code here

if __name__ == '__main__':
    useful_code()

现在,如果你python scriptname.py, then __name____main__所以打电话给useful_code()将立即执行。但如果你import scriptname(假设您已经进行了设置,以便您可以使用正确的方法来执行此操作sys.path等等)这不会导致useful_code立即运行;相反,调用者决定是否以及何时真正想要运行此函数(或模块中的其他函数,如果它包含多个函数)。

进一步说,f'{file}'只是一种非常笨拙的表达方式file (or str(file)如果变量还不是字符串)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数中的 Subprocess.call() 不会暂停调用该函数的脚本 的相关文章

随机推荐