Python:如何在从命令行调用时启用kwargs?(也许与argparse)

Dr.*_*erg 8 python command-line kwargs python-2.7 argparse

假设我有模块myscript.py; 该模块是生产代码,通常称为%dir%>python myscript.py foo bar.

我想扩展它以获取关键字参数.我知道我可以使用下面的脚本来获取这些参数,但不幸的是,我们必须使用它来调用它

%dir%>python myscript.py main(foo, bar).

我知道我可以使用该argparse模块,但我不知道该怎么做.

import sys

def main(foo,bar,**kwargs):
    print 'Called myscript with:'
        print 'foo = %s' % foo
        print 'bar = %s' % bar
        if kwargs:
            for k in kwargs.keys():
                print 'keyword argument : %s' % k + ' = ' + '%s' % kwargs[k]   

if __name__=="__main__":
    exec(''.join(sys.argv[1:]))
Run Code Online (Sandbox Code Playgroud)

use*_*559 16

@Moon用类似的解决方案打败了我,但我建议事先进行解析并实际传递kwargs:

import sys

def main(foo, bar, **kwargs):
    print('Called myscript with:')
    print('foo = {}'.format(foo))
    print('bar = {}'.format(bar))
    for k, v in kwargs.items():
        print('keyword argument: {} = {}'.format(k, v))

if __name__=='__main__':
    main(sys.argv[1], # foo
         sys.argv[2], # bar
         **dict(arg.split('=') for arg in sys.argv[3:])) # kwargs

# Example use:
# $ python myscript.py foo bar hello=world 'with spaces'='a value'
# Called myscript with:
# foo = foo
# bar = bar
# keyword argument: hello = world
# keyword argument: with spaces = a value
Run Code Online (Sandbox Code Playgroud)


Moo*_*sez 6

如果你想像在 main 函数中一样传入关键字参数key=value,你可以这样做:

import sys

def main(foo, bar, *args):
    print "Called my script with"

    print "foo = %s" % foo
    print "bar = %s" % bar

    for arg in args:
        k = arg.split("=")[0]
        v = arg.split("=")[1]

        print "Keyword argument: %s = %s" % (k, v)


if __name__ == "__main__":
    if len(sys.argv) < 3:
        raise SyntaxError("Insufficient arguments.")
    if len(sys.argv) != 3:
        # If there are keyword arguments
        main(sys.argv[1], sys.argv[2], *sys.argv[3:])
    else:
        # If there are no keyword arguments
        main(sys.argv[1], sys.argv[2])
Run Code Online (Sandbox Code Playgroud)

一些例子:

$> python my_file.py a b x=4
Called my script with
foo = a
bar = b
Keyword argument: x = 4
$> python my_file.py foo bar key=value
Called my script with
foo = foo
bar = bar
Keyword argument: key = value
Run Code Online (Sandbox Code Playgroud)

但是,这假设键和值之间没有任何空格,是key = value行不通的。

如果您正在寻找--argument各种关键字参数,您应该使用argparse.


che*_*ner 5

首先,您不会传递任意Python表达式作为参数。这是脆弱且不安全的。

要设置参数解析器,您需要定义所需的参数,然后解析它们以生成一个Namespace对象,该对象包含命令行调用指定的信息。

import argparse
p = argparse.ArgumentParser()
p.add_argument('foo')
p.add_argument('bar')
p.add_argument('--add-feature-a', dest='a', action='store_true', default=False)
Run Code Online (Sandbox Code Playgroud)

在您的代码__main__块中,您将解析参数,然后将从产生的字典传递Namespacemain

if __name__ == '__main__':
    args = p.parse_args()
    main(**vars(args))
Run Code Online (Sandbox Code Playgroud)

然后,您将在一行中调用脚本

# foo = "3", bar = "6", a = True
python myscript.py 3 6 --add-feature-a
Run Code Online (Sandbox Code Playgroud)

要么

# foo = "moo", bar="7.7", a = False
python myscript.py moo 7.7
Run Code Online (Sandbox Code Playgroud)

您可以做很多事情argparse,但这是一个简单的示例,可将其产生的价值转化为main


Dav*_*vid 5

在两行代码中,我可以获得 args 和 kwargs,我可以像标准 args 和 kwargs 一样操作它们:

import sys


if __name__=='__main__':
  argv=argv[1:] 
  kwargs={kw[0]:kw[1] for kw in [ar.split('=') for ar in argv if ar.find('=')>0]}
  args=[arg for arg in argv if arg.find('=')<0]

  #and you can the use args and kwargs as so:
  if 'reset' in args:
    do_some_functions_with_reset()
  a_device_var=kwargs.get('device',False):
  #or whatever you want to do with args and kwargs
Run Code Online (Sandbox Code Playgroud)

结果是:

$python test.py reset device=foo format=1 bar
->args=['reset','bar']
->kwargs={'device':'foo','format':'1'}
Run Code Online (Sandbox Code Playgroud)