简体   繁体   中英

python argparse subparser assign value to variable

i want to assign the subparser values to a variable like 'rport' so when the user call argument with value like

python example.py -sock connectmode -rport 10000 

the rport variable take the 10000 int value but that code return error in the last line in 'rport = '

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

notes : the subparsers is for a function is called 'socketfunc' i wanted them to be a subargs for '-sock' argument when i execute : 'python example.py -sock connectmode -h return the secondary_parser args [!]another note : the rport and rhost variables is global to make their values available to all functions

any help ! and thanks.

the code is :

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
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'}

Using argument parser:

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

Hope this will solve your problem to get command line argument.

hello guys the soloution is that replace rport = args.rport with rport=args.remoteport the short arg doesnt conain the value but should specify the long arg name

thanks for all.

It's hard to figure out what you want. The description is poorly formated and rambling. But I'll try to explain what your code is doing.

Simplified a bit:

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)

With the connectmode values:

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

Why? Because you defined -rhost as a required argument for the connectmode subparser. If I provide both:

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

In this case args.remoteport would work. args.rport would not, because the dest is taken from the long name, -- , not the short one.

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

args.remoteport would not work here because that argument is not defined for this subparser.

-sock is a simple True/False argument, and has nothing to do with the subparsers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM