Search code examples
pythonargumentsargv

Python going with argv or *arg?


If using sys.argv would there be any reason to use the *arg or would sys.argv be able to do everything that *arg would?

For instance:

>>>def test(*arg):
>>>    return arg
>>>
>>>print test('hello','salut','hola')
>>>('hello','salut','hola')

When I use sys.argv inside a file called trial.py that I call from the command-line:

import sys
def test(argument):
    return argument

print test(sys.argv[1])


python trial.py 'hello','salut','hola'
hello,salut,hola

Or is argv really geared to receiving just one argument and is it possible for argv to have more than 2 items(argv[0],argv[1])?


Solution

  • sys.argv is a list containing all the arguments your python script was invoked with on the command line, with the script itself considered to be "argument 0".

    It's an ordinary variable, same as any other variable that happens to contain a list. So there is no "choice" between sys.argv and *arg. *arg is syntax used for unpacking a list (or other sequence) to pass as multiple arguments to a call. You can use this syntax when passing sys.argv, as you can with any other variable containing a list. Or you can leave off the * and pass the whole list as one argument. Again, whether the list happens to be sys.argv is irrelevant to what happens.

    I think the source of your confusion is that the shell from which you're invoking your python script doesn't consider multiple arguments to be separated the same way Python does. In Python, you separate multiple arguments with commas, so 'hello','salut','hola' would be 3 arguments (although it would be more usual style to put spaces after the commas).

    In most shells OTOH, arguments are separated by whitespace. 'hello','salut','hola' does not contain any white space, so it's just one argument. So it shows up in the Python list in sys.argv as one item. Nothing magic has happened to concatenate multiple arguments into one for you; it's just that there only ever was one argument. The way to get the Python-level sys.argv to have 3 items would be to invoke your script like this:

    python trial.py 'hello' 'salut' 'hola'
    

    It also looks like you're using quotes in the shell command line the way you would in Python. In most shells, you don't always need to quote strings because everything is a string. Instead, quotes are used to tell the shell that a string containing whitespace is actually one argument with whitespace in it, rather than multiple arguments, or to disable certain special processing that shells do by default everywhere.

    In Python 'hello' is necessary to make the string "hello", so that Python doesn't try to read it as a variable hello. But in shells, 'hello' and hello are both identical, and just mean the string "hello". But it would also be possible to write he'll'o with only a part of the string quoted. This just changes how the shell processes whitespace and other special characters inside the quotes, but still results in the same string "hello". This is why the shell is interpreting your form 'hello','salut','hola' as the string "hello,salut,hola". There's no whitespace outside the quotes, so the 3 words doesn't get treated as separate arguments, and after doing their job of telling the shell how to process special characters the quotes just disappear.