使用Python和Biopython合并FASTA文件的代码故障求助
问题原因分析
第一个版本报错原因
SeqIO.write()要求传入的第一个参数是SeqRecord对象组成的可迭代对象,你第一次代码里定义的output = [infile1, infile2]是两个文件名字符串组成的列表,字符串没有id属性,因此触发AttributeError。
第二个版本读取失败原因
第二个版本的合并逻辑是正确的,list(chain(seq1, seq2))确实可以把两个SeqRecord列表合并,现在读取第二个文件得到的序列数为0,问题出在第二个FASTA文件本身的读取环节,和合并逻辑无关。
排查步骤
- 首先验证第二个文件的基础属性:在运行脚本的目录执行
ls -lh banco_de_dados_ITS.fasta,确认文件大小不为0,且运行脚本的用户有该文件的读权限。 - 单独测试第二个文件的读取有效性,运行如下测试代码:
from Bio import SeqIO seq_list = list(SeqIO.parse("banco_de_dados_ITS.fasta", "fasta")) print("读取到的序列数:", len(seq_list)) # 如果长度为0,打印文件原始内容检查格式 if len(seq_list) == 0: with open("banco_de_dados_ITS.fasta", "r") as f: print(f.read()[:200]) # 打印前200个字符看格式是否正常
- 检查FASTA格式合规性:
- 每个序列必须以
>开头作为ID行,ID行后紧跟序列行 - 序列中不能出现未被识别的非法字符
- 如果文件是在Windows系统下生成的,检查是否带有UTF-8 BOM头,Python2的BioPython解析器无法识别带BOM的文件,可以用文本编辑器转成无BOM的UTF-8格式,或者读取的时候先去掉BOM头。
- 每个序列必须以
优化后的最终代码
支持任意多个输入FASTA文件,不用固定为2个输入:
import sys from Bio import SeqIO from itertools import chain # 使用方法:python join_fasta.py 输入1.fasta 输入2.fasta 输入3.fasta ... 输出.fasta if len(sys.argv) < 3: print("参数错误,使用方法:python join_fasta.py 输入1.fasta [输入2.fasta ...] 输出.fasta") sys.exit(1) infiles = sys.argv[1:-1] outfile = sys.argv[-1] all_seq = [] for idx, fname in enumerate(infiles): seqs = list(SeqIO.parse(fname, "fasta")) print("第{}个输入文件:{},读取到序列数:{}".format(idx+1, fname, len(seqs))) all_seq.append(seqs) all_seq = list(chain.from_iterable(all_seq)) print("合并后总序列数:{}".format(len(all_seq))) SeqIO.write(all_seq, outfile, "fasta") print("结果已写入:{}".format(outfile))
内容的提问来源于stack exchange,提问作者Pedro Henrique
相关产品推荐
相关产品推荐

