You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>
]

问题根源

  1. 重复添加同一个对象:只创建了一个DnaSeq实例,循环里每次修改它的属性后就添加到列表,导致列表全是同一个对象的引用,数量等于文件行数。
  2. FASTA格式解析逻辑错误:你的FASTA文件里序列行也带了>,且没有正确的序列收集逻辑——应该在遇到新的accession时,先把上一个完整的序列存入列表,再处理新序列。
  3. 未清洗行内容:读取的行包含换行符和多余空格,没有正确提取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__()

修改说明

  1. 不再复用单个对象:每次遇到新的accession时,创建新的DnaSeq实例添加到列表,确保每个对象对应独立序列。
  2. 正确的序列收集逻辑:遇到新accession时先保存上一个序列,循环结束后处理最后一个序列,保证不遗漏。
  3. 清洗行内容:跳过空行,去掉accession的>符号,清除序列中的空格,确保内容干净。
  4. 兼容多行序列:如果后续FASTA的序列分多行,代码能自动拼接,无需额外修改。

修改后调用read_dna('ex1.fa')会得到6个独立的DnaSeq对象,符合预期。

内容的提问来源于stack exchange,提问作者pythonhelpneeded

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:02:54