簡體   English   中英

argparse-如何通過kwargs或argv傳遞給方法

[英]argparse - how pass to a method with kwargs or argv

我一直在尋找一種將**kwargs*argvargparse 我將從硬代碼到動態方式。

這是我的硬代碼,以及如何使用它的示例。

def get_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument("-r",
                        "--range",
                        dest="r",
                        nargs=8,
                        help="AddRange Parameters")
    parser.add_argument("-p",
                        "--parameters",
                        dest="p",
                        nargs=8,
                        help="SetDefaults as Parameters")
    parser.add_argument("-r",
                    "--range",
                    dest="r",
                    nargs=8,
                    help="AddRange Parameters")
    return parser

"""Create a Template for a Job"""
def create_Template(temp3_,temp_tournsize,temp_popsize,temp0_,temp1_,temp_ngen,temp_run,tmpverb):
    #single GA job
    logging.basicConfig(level=logging.DEBUG)
    template = job.JobTemplate(runGASimple)
    print tmpverb
    template.setDefaults(temp3=temp3_, tournsize=temp_tournsize, popSize=temp_popsize, temp0=temp0_, temp1=temp1_, ngen=temp_ngen, number_of_runs=temp_run, verbose=tmpverb)
    return template

"""Run a simple Job"""
def ajob_run(template):
    ajob = job.Job(template)
    ajob.run()
    pass

    """change Default params with AddRange"""
def add_Range(var_temp0,var_start,var_end,var_stepSize,var_temp1,var_start2,var_end2,var_stepSize2,tmp_template):
    jobCreator = job.JobCreator()
    #jobCreator.addRange('temp0', start=0.0, end=1.0, stepSize=0.1)
    jobCreator.addRange(var_temp0, start= var_start, end=var_end, stepSize=var_stepSize)
    #jobCreator.addRange('temp1', start=0.0, end=1.0, stepSize=0.1)
    jobCreator.addRange(var_temp1, start=var_start2, end=var_end2, stepSize=var_stepSize2)
    # all other params will take defaults
    jobs = jobCreator.generateJobs(tmp_template)

    return jobs

"""Create a Batchjob from Jobs"""
def batch_Job(tmp_jobs):
    batchJob = job.BatchJob(tmp_jobs, 5)

    return batchJob


if (__name__ == "__main__"):

    args = get_parser().parse_args()
    if (args.p and args.r):
        print 'AddRange with Parameters Input Start:'
        temp = create_Template(float(args.p[0]),int(args.p[1]),int(args.p[2]),float(args.p[3]),float(args.p[4]),int(args.p[5]),int(args.p[6]),ast.literal_eval(args.p[7]))
        tmpjobs = add_Range(args.r[0],float(args.r[1]),float(args.r[2]),float(args.r[3]),args.r[4],float(args.r[5]),float(args.r[6]),float(args.r[7]),temp)
        results = batch_Job(tmpjobs)


        print 'AddRange with Parameters Input Ende.'
    elif (args.p):
            print 'Parameters Input Start:'
        ajob_run(create_Template(
        float(args.p[0]),
        int(args.p[1]),
        int(args.p[2]),
        float(args.p[3]),
        float(args.p[4]),
        int(args.p[5]),
        int(args.p[6]),
        ast.literal_eval(args.p[7])))
        print 'Parameters Input Ende.'

CLI.py -p 0.8 20 20 0.5 0.5 20 1 False

然后是來自框架結果的大量輸出。

我的方法預期如此。 變量名稱將來可以更改。

template.setDefaults(mux=0.8, tournsize=20, rangeSize=20, temp0=0.5, temp1=0.5, ngen=20, number_of_runs=1, verbose=False)

jobCreator.addRange('temp0', start=0.0, end=1.0, tournStep=0.1)

jobCreator.addRange('temp1', start=0.0, end=1.0, turns=4)

會像這樣更改它:

setDefaults(**kwargs)

addRange(paraName,**kwargs)

我期望這樣:

CLI.py -p temp0=1 temp1=0.4 ....temp6=8 ... -r temp0 start=0 end=1 tournStep=0.1
or
CLI.py -p hn0=1 bn1=0.4 ....tp6=8 ... -r temp1 start=0 end=1 turns=4

然后將輸入的變量名轉換為:

setDefaults()

addRange()

但是我需要argparse ,因為我將構建一個命令行界面。

我忘記了其他方法的一些細節:

    """change Default params with AddSpecific"""
def add_Specific(tmp_template,paraName,*params):
    jobCreator = job.JobCreator()
    #jobCreator.addSpecific('temp0', 0.1,0.2,0.3,0.4,....,0.7,...)
    jobCreator.addRange(paraName, params)
    # all other params will take defaults
    jobs = jobCreator.generateJobs(tmp_template)
    return jobs

那是正確的方法嗎?

在這里, parameters參數將具有8對的列表,例如:

CLI.py -p argname1=v1 ... argname8=v8

(顯然, argnameN應該是所需函數的參數名稱)。

然后,您可以輕松地將args.p (即['argname1=v1', ... 'argname8=v8'] )轉換為字典:

def convert_value(v):
    try:
        return float(v) if '.' in v else int(v)
    except ValueError:
        # v is not a number
        return v

params = dict([convert_value(n) for n in pair.split('=')] for pair in args.p)

並將其傳遞給您的函數:

"""Create a Template for a Job"""
def create_Template(params):
    #single GA job
    logging.basicConfig(level=logging.DEBUG)
    template = job.JobTemplate(runGASimple)
    print tmpverb
    template.setDefaults(**params)
    return template

通過創建兩個不同的范圍參數,可以對范圍參數執行相同的操作:

"""change Default params with AddRange"""
def add_Range(var_1, var_2, tmp_template):
    jobCreator = job.JobCreator()
    #jobCreator.addRange('temp0', start=0.0, end=1.0, stepSize=0.1)
    jobCreator.addRange(**var_1)
    #jobCreator.addRange('temp1', start=0.0, end=1.0, stepSize=0.1)
    jobCreator.addRange(**var_2)
    # all other params will take defaults
    jobs = jobCreator.generateJobs(tmp_template)

請注意Gall的答案-它可能會大大簡化您的代碼。 對於動態“ argparse”,請嘗試以下操作:

#!/usr/bin/env python

from __future__ import print_function
from __future__ import unicode_literals
import argparse


args_d = {
  '-r': {
    'flags': ['-r', '--range'],
    'nargs': 8,
    'help': 'AddRange Parameters',
    'dest': 'r'
  },
  '-p': {
    'flags': ['-p', '--parameters'],
    'nargs': 8,
    'help': 'SetDefaults as Parameters',
    'dest': 'p'
  }
}

def setup_parser(args_d):
    parser = argparse.ArgumentParser()

    for k,v in args_d.items():
        if 'flags' in v:
            flags = v['flags']
            del v['flags']
        parser.add_argument(*flags, **v)

    return parser

if __name__ == "__main__":

    args = setup_parser(args_d).parse_args()

    print(args)

您仍然必須動態生成字典。 您可以嘗試為此使用“檢查”模塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM