python argparse subparser 为变量赋值

Posted

技术标签:

【中文标题】python argparse subparser 为变量赋值【英文标题】:python argparse subparser assign value to variable 【发布时间】:2018-06-24 03:33:41 【问题描述】:

我想将子解析器的值分配给像“rport”这样的变量,所以当用户调用具有像

这样的值的参数时
python example.py -sock connectmode -rport 10000 

rport 变量采用 10000 int 值,但该代码在 'rport = ' 的最后一行返回错误

AttributeError: 'Namespace' object has no attribute 'rport'

注释:子解析器用于一个名为“socketfunc”的函数 我希望它们成为“-sock”论点的子参数 当我执行时:'python example.py -sock connectmode -h 返回 secondary_parser 参数 [!]另一个注意事项:rport 和 rhost 变量是全局变量,以使它们的值可用于所有函数

任何帮助!谢谢。

代码是:

import argparse
import socket
parser = argparse.ArgumentParser(epilog='\tExample: \r\npython ' + sys.argv[0])
parser.error = parser_error
parser._optionals.title = "OPTIONS"
subparsers = parser.add_subparsers(help='Specify secondary options')
global rport , rhost
secondary_parser = subparsers.add_parser('connectmode', help='sock argument connectmode')
listenmode_parser = subparsers.add_parser('listenmode',help='sock argument listenmode')
parser.add_argument('-sock','--socket',help="tcp socket functions [!] support only ipv4 for now",action="store_true")
secondary_parser.add_argument('-rport','--remoteport',help="destination port to connect to",required=True,action='store')
secondary_parser.add_argument("-rhost",'--destination',help="destination host ip addr",required=True,action='store')
secondary_parser.set_defaults(func=socketfunc)
listenmode_parser.set_defaults(func=socketfunc)
args = parser.parse_args()
rport = args.rport

【问题讨论】:

第二行,试试parser = argparse.ArgumentParser(epilog='\tExample: \r\npython ' + sys.argv[0])而不是parser = argparse.ArgumentParser(epilog='\tExample: \r\npython ' + sys.argv[0] + ") 嗨,伙计,我现在的问题是如何使 rport 变量采用子解析器 rport 参数的值 @mahmoudadel 将 args = parser.parse_args() 替换为 args = vars(parser.parse_args()) 并获取值 rport = args.get('rport') 你试过rport = args.remoteport 吗? argparse 使用长参数名称命名其参数 【参考方案1】:
import sys

def getcmdlineargv(argv):
"""Function to get values from cmd line and converted into dictionary"""
   opts =   # dictionary to store key-value pairs.
   while argv:  # until arguments left to parse...
      if argv[0][0] == '-':  # Found a "-name value" pair.
        opts[argv[0]] = argv[1]  # Add key and value to the dictionary.
      argv = argv[1:]  # Reduce the argument list by copying it starting from index 1.
   return opts
argvDict = getcmdlineargv(sys.argv)
print(argvDict)

>>> python filename.py -sock connectmode -rport 10000
>>> '-sock': 'connectmode', '-rport': '10000'

使用参数解析器:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-sock", type=str, help='')
parser.add_argument("-rport", type=int, help='')
parsarg = vars(parser.parse_args())
print(parsarg.get('rport'))

>>> python filename.py -sock connectmode -rport 10000
>>> 10000

希望这能解决您获取命令行参数的问题。

【讨论】:

如何使用 argparse 而不是 sys 库来做到这一点? 感谢您的帮助,但您误解了我想要的方式,您将 rport 设为参数而不是子参数参数,但仅在我调用 -sock 参数时解析,那么将 rport 参数值分配给 rport 变量会很容易你明白我的意思吗?【参考方案2】:

大家好,解决方法是替换 rport = args.rportrport=args.remoteport 短参数不包含值,但应指定长参数名称

谢谢大家。

【讨论】:

【参考方案3】:

很难弄清楚你想要什么。描述的格式很差,而且杂乱无章。但我会尝试解释你的代码在做什么。

简单一点:

import argparse

parser = argparse.ArgumentParser()
parser._optionals.title = "OPTIONS"
subparsers = parser.add_subparsers(help='Specify secondary options')
global rport , rhost
secondary_parser = subparsers.add_parser('connectmode', help='sock argument connectmode')
listenmode_parser = subparsers.add_parser('listenmode',help='sock argument listenmode')
parser.add_argument('-sock','--socket',action="store_true")
secondary_parser.add_argument('-rport','--remoteport',required=True)
secondary_parser.add_argument("-rhost",'--destination',required=True)
secondary_parser.set_defaults(func='secondary')
listenmode_parser.set_defaults(func='listen')
args = parser.parse_args()
print(args)

使用connectmode 值:

1027:~/mypy$ python3 stack48264081.py  -sock connectmode -rport 10000 
usage: stack48264081.py connectmode [-h] -rport REMOTEPORT -rhost DESTINATION
stack48264081.py connectmode: error: the following arguments are required: -rhost/--destination

为什么?因为您将-rhost 定义为connectmode 子解析器的必需参数。如果我同时提供:

1031:~/mypy$ python3 stack48264081.py  -sock connectmode -rport 10000 -rhost foo
Namespace(destination='foo', func='secondary', remoteport='10000', socket=True)

在这种情况下args.remoteport 可以工作。 args.rport 不会,因为dest 取自长名称--,而不是短名称。

1034:~/mypy$ python3 stack48264081.py  listenmode
Namespace(func='listen', socket=False)

args.remoteport 在这里不起作用,因为该子解析器没有定义该参数。

-sock 是一个简单的 True/False 参数,与子解析器无关。

【讨论】:

我想要一个变量,该变量具有命令行中的远程端口子解析器值,以便在函数中使用它。你明白我的意思吗?我会试试 rport = args.remoteport 但请记住,listenmode 不会像设置那样创建args.remoteport 属性。您的使用代码必须考虑到这一点。

以上是关于python argparse subparser 为变量赋值的主要内容,如果未能解决你的问题,请参考以下文章

argparse:声明全局参数后无法获取 subparser_name

Python argparse - 向多个子解析器添加参数

带有可选子命令的 argparse 未按预期工作

有没有办法在 argparse 中添加一个已经创建的解析器作为子解析器?

Argparse 错误:python2.x 上的参数太少

带有所需子解析器的 Argparse