read_dna函数生成过多DnaSeq对象问题及修复咨询
修复FASTA文件读取生成DnaSeq对象数量错误的问题
原代码
DnaSeq类与read_dna函数
class DnaSeq: def __init__(self, accession, seq): self.accession = accession self.seq = seq def __len__(self): if self.seq is None or self.seq == '': raise ValueError return len(self.seq) def __str__(self): if self.accession is None or self.accession == '': raise ValueError return f"<DnaSeq accession='{self.accession}'>" def read_dna(filename): DnaSeq_objects = [] new_dna_seq = DnaSeq("s1", "AAA") with open(filename, 'r') as seq: for line in seq.readlines(): if line.startswith('>'): new_dna_seq.accession = line else: new_dna_seq.seq = line.strip() DnaSeq_objects.append(new_dna_seq) return DnaSeq_objects
待读取的FASTA文件内容
> s0 > ATGTTTGTTTTTCTTGTTTTATTGCCACTAGTCTCTAGTCAGTGT GTTAATCTTACAACCAGAACTCAAT > s1 > GTTAATCTTACAACCAGAACTCAATTACCCCCTGCATACACTAATTCTTTCACACGTGGTGTTTATTACCCTGACAAAGTTTTCAGATCCTCAGTTTTACATTCAACTCAGGACTTGTTCTTACCTTTCTTTTCCAATGTTACTTGGTTCCATGCTATACATGTC > s2 > ACTCAGGACTTGTTCTTACCTTTCTTTTCCAATGTTACTTGGTTCCATGCTATACATGTCTCTGGGACCAATGGTACTAAGAGGTTTGATAACCCTGTCCTAC > s3 > TCTGGGACCAATGGTACTAAGAGGTTTGATAACCCTGTCCTACCATTTAATGATGGTGTTTATTTTGCTTCCACTGAGAAGTCTAACATAATAAGAGGCTGGATTTTTGGTACTACTTTAGATTCGAAGACCCAGTCCCT > s4 > AGACCCAGTCCCTACTTATTGTTAATAACGCTACTAATGTTGTTATTAAAGTCTGTGAATTTCAATTTTGTAATGATCCATTT > s5 > TTTGTAATGATCCATTTTTGGGTGTTTATTACCACAAAAACAACAAAAGTTGGATGGAAAGTGAGTTCAGAGTTTATTCTAGTGCGA
当前错误输出
调用read_dna('ex1.fa')后得到12个重复的对象引用:
[<__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820>, <__main__.DnaSeq object at 0x000001C67208F820> ]
问题根源
- 重复添加同一个对象:只创建了一个
DnaSeq实例,循环里每次修改它的属性后就添加到列表,导致列表全是同一个对象的引用,数量等于文件行数。 - FASTA格式解析逻辑错误:你的FASTA文件里序列行也带了
>,且没有正确的序列收集逻辑——应该在遇到新的accession时,先把上一个完整的序列存入列表,再处理新序列。 - 未清洗行内容:读取的行包含换行符和多余空格,没有正确提取accession和序列内容。
修改后的代码
修正的read_dna函数
def read_dna(filename): DnaSeq_objects = [] current_accession = None current_seq = None with open(filename, 'r') as seq_file: for line in seq_file: line = line.strip() if not line: # 跳过空行 continue if line.startswith('>'): # 如果已有正在处理的序列,先保存 if current_accession is not None and current_seq is not None: DnaSeq_objects.append(DnaSeq(current_accession, current_seq)) # 提取新的accession,去掉>和前后空白 current_accession = line[1:].strip() current_seq = "" else: # 拼接序列(兼容多行序列) current_seq += line.replace(' ', '') # 去除序列中的空格 # 处理最后一个未存入的序列 if current_accession is not None and current_seq is not None: DnaSeq_objects.append(DnaSeq(current_accession, current_seq)) return DnaSeq_objects
可选优化:DnaSeq类简化
class DnaSeq: def __init__(self, accession, seq): self.accession = accession self.seq = seq def __len__(self): if not self.seq: # 空字符串或None都触发报错 raise ValueError("序列不能为空") return len(self.seq) def __str__(self): if not self.accession: raise ValueError("accession不能为空") return f"<DnaSeq accession='{self.accession}'>" def __repr__(self): return self.__str__()
修改说明
- 不再复用单个对象:每次遇到新的accession时,创建新的
DnaSeq实例添加到列表,确保每个对象对应独立序列。 - 正确的序列收集逻辑:遇到新accession时先保存上一个序列,循环结束后处理最后一个序列,保证不遗漏。
- 清洗行内容:跳过空行,去掉accession的
>符号,清除序列中的空格,确保内容干净。 - 兼容多行序列:如果后续FASTA的序列分多行,代码能自动拼接,无需额外修改。
修改后调用read_dna('ex1.fa')会得到6个独立的DnaSeq对象,符合预期。
内容的提问来源于stack exchange,提问作者pythonhelpneeded
相关产品推荐
相关产品推荐

