Argparse: Check if any arguments have been passed

My script should start a demo mode, when the no parameters are given. I tried this:

args = parser.parse_args()
if len(args) == 0:
    run_demo()
else:
    # evaluate args

Which gives a *** TypeError: object of type 'Namespace' has no len() as args is no list.

How would I achieve what I want?


If your goal is to detect when no argument has been given to the command, then doing this via argparse is the wrong approach (as Ben has nicely pointed out).

Think simple! :-) I believe that argparse does not depopulate sys.argv. So, if not len(sys.argv) > 1, then no argument has been provided by the user.


argparse lets you set (inside a Namespace object) all the variables mentioned in the arguments you added to the parser, based on your specification and the command line being parsed. If you set a default, then those variables will have that default value if they weren't seen on the command line, they won't be absent from the Namespace object. And if you don't specify a default, then there is an implicit default of None. So checking the length of the Namespace object, however you manage to do it, doesn't make sense as a way to check whether any arguments were parsed; it should always have the same length.

Instead, if you know you've got a bunch of arguments with no defaults and you want to check whether any of them were set to any non-None value... do that. You can use a list comprehension and the vars function to loop over them without having to duplicate the list of names from the add_argument calls, as shown in Martijn's answer.

It gets a little trickier if some of your arguments have default values, and more so if they have default values that could be explicitly provided on the command line (e.g. a numeric argument that defaults to 0 makes it impossible to tell the default from the user providing 0). In that case I'm not sure that there's a general solution that always works without knowledge of what the arguments are.


If one really needs the argument number (for whatever reason). I have found this code very helpful (but do not know how much optimised it is, and I'd appreciate any comment on it).

args = parser.parse_args()
print( len( vars(args) ) )

This version counts only the -xx parameters and not any additional value passed.

If one wants everything (also the values passed), then just use len(sys.argv) as previously mentioned.


Don't use argparse. Instead just use sys.argv. argparse creates a Namespace, so it will always give you a "dict" with their values, depending on what arguments you used when you called the script.

Here's what I've done in the past:

args = parser.parse_args()
if len(sys.argv) == 1:
    parser.print_help()
    sys.exit()
return args

I know it's an old thread but I found a more direct solution that might be useful for others as well:

You can check if any arguments have been passed:

if any(vars(args).values()):
    # evaluate args

Or, if no arguments have been passed(note the not operator):

if not any(vars(args).values()):
    run_demo()

Explanation:

  • parse_args() returns a "Namespace" object containing every argument name and their associated value. Example: Namespace(arg1='myfile.txt', arg2='some/path/to/some/folder')

  • If no arguments have been passed, parse_args() will return the same object but with all the values as None. Example: Namespace(arg1=None, arg2=None)

This object is not iterable, though, so you have to use vars() to turn it into a dict so we can access the values.

Finally, as we now have a dict on hands, we can get all the values(in a list), with .values(), and use the built-in any() function to check if any of the values is not None. To make it clearer: any() returns False if there isn't a single value that is not None, False or 0(check the docs for reference) in the list you've fed to it.

Hope it helps.