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

Python3 argparse参数处理报错:Args.__new__()缺失必填位置参数'dell'

Python3 argparse参数处理报错:Args.new()缺失必填位置参数'dell'

看起来你遇到的问题根源在于NamedTuple的定义和参数处理逻辑不匹配,咱们一步步拆解问题并修复:

问题分析

  1. NamedTuple字段定义错误:你定义的Args类包含三个必填字段rna、ins、dell,但你的需求里ins和dell是可选参数,必须给这两个字段设置默认值,否则实例化Args时必须传入所有三个参数,哪怕用户没指定部分可选参数。
  2. get_args()分支逻辑遗漏场景:当用户同时传入--ins和--dell时,你的代码没有对应的分支处理,会进入某个不完整的分支(比如elif args.rna and args.ins),只传递rna和ins,导致缺少dell参数引发报错。
  3. argparse的--ins参数配置错误:type=list在argparse中无法正确解析你传入的'4 T',因为type是用来转换单个参数的类型,你需要用nargs='+'来接收多个参数值。

解决方案与修复后的代码

下面是修复后的完整代码,我标注了关键修改点:

#!/usr/bin/env python3

import argparse
from typing import NamedTuple, Dict, List, Optional
import csv

# 1. 给可选字段设置默认值为Optional类型的None
class Args(NamedTuple):
    rna: str
    ins: Optional[List] = None  # 可选参数,默认None
    dell: Optional[int] = None  # 可选参数,默认None

def get_args() -> Args:
    parser = argparse.ArgumentParser(description='translating mRNA', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('rna', metavar='RNA seq', type=str)
    # 2. 修正--ins的配置,用nargs='+'接收多个参数,type=str(因为要接收位置和碱基)
    parser.add_argument('--ins', '-i', nargs='+', help='add the insertion position and the base to test its frameshift effect', default=None)
    parser.add_argument('--dell', '-d', type=int, help='add the position of the deleted base to test its frameshift effect', default=None)
    
    args = parser.parse_args()
    
    # 3. 简化逻辑,直接返回Args实例,因为所有可选参数都有默认值
    return Args(
        rna=args.rna,
        ins=args.ins,
        dell=args.dell
    )

def main():
    args = get_args()
    codons = codon_dict()
    rna = args.rna
    ins = args.ins
    dell = args.dell

    protein = translator(rna)
    print(f'protein_original:\n{protein}')

    if ins and not dell:
        # 注意:这里ins[0]是字符串,需要转成int
        ins_pos = int(ins[0])
        ins_mut_rna = list(rna)
        ins_mut_rna.insert(ins_pos + 1, ins[1])
        ins_mut_protein = translator(''.join(ins_mut_rna))  # 转成字符串传给translator
        print(f'frameshift protein\n{ins_mut_protein}')
    elif dell and not ins:
        dell_mut_rna = list(rna)
        dell_mut_rna.pop(dell + 1)
        dell_mut_protein = translator(''.join(dell_mut_rna))
        print(f'frameshift\n{dell_mut_protein}')
    elif ins and dell:
        ins_pos = int(ins[0])
        if ins_pos > dell:
            ins_dell_rna = list(rna)
            ins_dell_rna.insert(ins_pos + 1, ins[1])
            ins_dell_rna.pop(dell + 1)
            final_prot = translator(''.join(ins_dell_rna))
        else:
            dell_ins_rna = list(rna)
            dell_ins_rna.pop(dell + 1)
            dell_ins_rna.insert(ins_pos + 1, ins[1])
            final_prot = translator(''.join(dell_ins_rna))
        print(f'frameshift protein\n{final_prot}')

def translator(rna: str) -> str:
    prot = []
    codons = codon_dict()
    steps = [i for i in range(0, len(rna), 3)]
    rna_codons = []
    for step in steps:
        rna_codons.append(rna[step:step + 3])
    
    # 处理找不到AUG的情况,避免ValueError
    if 'AUG' not in rna_codons:
        return "No start codon (AUG) found"
    
    start = rna_codons.index('AUG')
    rna_codons = rna_codons[int(start):]
    
    for codon in rna_codons:
        if len(codon) < 3:  # 处理最后一个不完整的密码子
            break
        if codon in codons:
            if codons[codon] == 'Stop':
                break
            prot.append(codons[codon])
    return ''.join(prot)

def codon_dict() -> Dict:
    mydict = {}
    with open('codon_table.csv', mode='r') as infile:
        reader = csv.reader(infile)
        next(reader)  # 跳过表头(如果你的csv有表头的话)
        for rows in reader:
            k = rows[0]
            v = rows[2]
            mydict[k] = v
    return mydict

if __name__ == '__main__':
    main()

关键修改说明

  1. NamedTuple默认值:给ins和dell设置Optional类型和默认值None,这样创建Args实例时可以只传rna,或者传任意组合的可选参数。
  2. argparse的--ins参数:用nargs='+'让它接收多个参数(比如4 T),这样args.ins会是一个列表['4', 'T'],之后需要把位置转成整数。
  3. 简化get_args()逻辑:不需要复杂的分支判断,直接把所有参数传入Args实例即可,因为可选参数都有默认值。
  4. translator函数修复:添加了找不到AUG的处理,以及最后一个不完整密码子的处理,避免报错。
  5. main函数的变量统一:同时处理ins和dell时,统一用final_prot变量,避免原代码中变量名不一致导致的报错。

测试命令

现在你可以用以下命令测试:

python3 prot.py AUGUUUAUG -d 4 -i 4 T

注意不需要给4 T加引号,nargs='+'会自动把它们解析成列表。

备注:内容来源于stack exchange,提问作者Younes Abuelayyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 08:04:38