Python 如何从交互式解释器调用函数并为argparse传递参数?
我在文件Python 如何从交互式解释器调用函数并为argparse传递参数?,python,arguments,command,line,argparse,Python,Arguments,Command,Line,Argparse,我在文件test.py中定义了一个Python函数myFunc。我想在交互模式下从Python解释器测试这个函数,并将argparse的命令行参数传递给parse。我在Python解释器中输入testimportmyfunc的。然后我希望能够在交互模式下运行“myFunc”。。。但要传递几个命令行参数 例如,我尝试了myFunc()arg1 arg2,但是Python解释器报告了一个语法错误:无效语法 如果我只是简单地键入myFunc(),函数确实会运行,但当然没有传递任何参数 我意识到我可以在
test.py
中定义了一个Python函数myFunc
。我想在交互模式下从Python解释器测试这个函数,并将argparse的命令行参数传递给parse。我在Python解释器中输入testimportmyfunc的。然后我希望能够在交互模式下运行“myFunc”。。。但要传递几个命令行参数
例如,我尝试了myFunc()arg1 arg2
,但是Python解释器报告了一个语法错误:无效语法
如果我只是简单地键入myFunc()
,函数确实会运行,但当然没有传递任何参数
我意识到我可以在我的代码中包含以下内容
if __name__ == "__main__":
myFunc()
然后,我可以从命令行“python test.py arg1 arg2”运行
这确实有效
但是,我想知道是否可以在交互模式下从Python解释器测试myFunc()
函数,并将argparse的命令行参数传递给parse
import argparse
from textwrap import dedent
import sys
def myFunc():
print "hello!"
print str(sys.argv)
parser = argparse.ArgumentParser(prog='Prog',
formatter_class= argparse.RawTextHelpFormatter,
description = dedent('Program to control Tycon TDDin2 Relay states'))
parser.add_argument('addr',
help='ip[:port] address of target device. ' \
'Port defaults to the snmp port of 161.')
parser.add_argument('relay',type=str, help='name of relay')
parser.add_argument('action', type=str, help='action = Open, Close or Cycle')
args = parser.parse_args()
print('args = ' + args.addr + ' ' + args.relay + ' ' + args.action)
parse_args
获取要解析的字符串列表;此参数的默认值是sys.argv[1://code>(实际上是None
,这将被解释为使用sys.argv[1://code>)的请求。将相同的参数添加到myFunc
,直接传递到parse_args
def myFunc(cli_args=None):
...
args = parser.parse_args(cli_args)
print('args = ' + args.addr + ' ' + args.relay + ' ' + args.action)
现在,您可以使用所需的任何参数列表调用myFunc
:
myFunc(["192.0.2.24", "foo", "Open"])
请记住,parse_args
如果无法成功解析args列表(而不仅仅是引发自定义异常),则会有效地退出解释器,因此,您需要准备捕获SystemExit
异常。无需修改myFunc
您可以在交互模式下修改sys.argv
,调用函数时将对其进行解析:
sanyash@sanyash-ub16:~/myrepos/trash$ python2.7
Python 2.7.12 (default, Dec 4 2017, 14:50:18)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import file
>>> import sys
>>> sys.argv = ['./file.py', 'some addr', 'some relay', 'some action']
>>> file.myFunc()
hello!
['./file.py', 'some addr', 'some relay', 'some action']
args = some addr some relay some action
>>>
在iTreactiveipython
控制台会话中,我可以复制粘贴您的函数(只需做一些更改),并轻松测试它
def myFunc(argv=None):
parser = argparse.ArgumentParser(prog='Prog',
formatter_class= argparse.RawTextHelpFormatter,
description = 'Program to control Tycon TDDin2 Relay states')
parser.add_argument('addr',
help='ip[:port] address of target device. ' \
'Port defaults to the snmp port of 161.')
parser.add_argument('relay',type=str, help='name of relay')
parser.add_argument('action', type=str, help='action = Open, Close or Cycle')
args = parser.parse_args(argv)
return args
测试空命令行:
In [7]: myFunc([])
usage: Prog [-h] addr relay action
Prog: error: the following arguments are required: addr, relay, action
An exception has occurred, use %tb to see the full traceback.
SystemExit: 2
/usr/local/lib/python3.6/dist-packages/IPython/core/interactiveshell.py:3299: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
ipython
捕获出口
myFunc()
将查看sys.argv
;生成相同的错误消息,因为会话命令行与此解析器无关
测试帮助:
In [8]: myFunc(['-h'])
usage: Prog [-h] addr relay action
Program to control Tycon TDDin2 Relay states
positional arguments:
addr ip[:port] address of target device. Port defaults to the snmp port of 161.
relay name of relay
action action = Open, Close or Cycle
optional arguments:
-h, --help show this help message and exit
An exception has occurred, use %tb to see the full traceback.
SystemExit: 0
....
使用有效列表进行测试:
In [9]: myFunc(['testpy','arg1','arg2'])
Out[9]: Namespace(action='arg2', addr='testpy', relay='arg1')
这将显示函数返回的args
命名空间。谢谢。。。这确实有效。我以前没有正确的调用语法。。。myFunc([“192.0.2.24”,“foo”,“Open”])这是您在捕获SystemExit异常的重要性方面提出的一个非常好的观点。您可能只需要使用monkey patch或mockArgumentParser。错误也可以是
。在测试期间通常不赞成全局状态的变化。@chepner,argparse
的unittest文件通过修改sys.argv
来测试解析器。这与真实世界中的命令行使用尽可能接近。它还通过parse_args(alist)
进行测试。Syayas正在演示一个交互式测试,而不是一个FrimunUnTest.给定代码< >错误<代码>调用<代码> sys .EXECU/<代码>,而不是简单地引发异常,我不会考虑<代码> AgPARSE> 一个好实践的典范.