-3

I've two functions, and I want to choose function message() or function number() on a UNIX terminal.

This example I define the function will be used inside if __name__ == "__main__"::

import sys

def message(m=sys.argv[2]):
    print(" {} ".format(m))


if __name__ == "__main__":
    message()

At terminal Inputting:

$python test.py python!

Outupts:

python!

Then when I've two functions and call just one of them:

import sys

def message(m=sys.argv[1]):
    print(" {} ".format(m))

def number(n=sys.argv[1]):
    print(" {} ".format(n+2))

if __name__ == "__main__":
    #code that should be here
Shapi
  • 5,493
  • 4
  • 28
  • 39

2 Answers2

2

You definitively asked the wrong question. Your question is "how do arguments work on Python", and for working with arguments you have two options I'm aware of:

  • Using sys.argv: you need to write something like if "message" in sys.argv
  • Using argparse which is a far better solution
  • Could you outline *how* you would use `argparse` for this? – jonrsharpe Oct 22 '15 at 10:50
  • @jonrsharpe there are multiple usage examples that I'll not write here, as they are in the documentation. –  Oct 22 '15 at 10:58
  • That is [not very useful](http://meta.stackexchange.com/questions/225370/your-answer-is-in-another-castle-when-is-an-answer-not-an-answer). – jonrsharpe Oct 22 '15 at 10:59
  • so dumping the documentation is a useful example? –  Oct 22 '15 at 11:00
  • I'm not saying you should just "*[dump] the documentation"* - I'm asking you to provide a minimal example that shows *how* you could solve the OP's problem with `argparse`, rather than effectively just saying *"go and read the `argparse` docs"*, which is a comment at best. – jonrsharpe Oct 22 '15 at 11:02
1

The canonical (and, in my view, correct) way to do this is to create a mapping of argument values to functions, which is simple to implement, efficient and easily scalable:

import sys

def message(m):
    print(" {} ".format(m))

def number(n):
    print(" {} ".format(int(n) + 2))  # you can't add integers to strings...

FUNCTIONS = {
    'message': message, 
    'number': number
}

if __name__ == "__main__":
    FUNCTIONS[sys.argv[1]](*sys.argv[2:])

Note the use of * to pass the rest of the arguments to the function - see What does ** (double star) and * (star) do for parameters?. This has removed the requirement for sys.argv to have a third value to create the functions, which could be a problem if you decide to reuse those functions elsewhere.

This will raise a KeyError if the user enters an invalid function name; you can handle this and give them a more specific error message if you like (either with sys.argv[1] in FUNCTIONS, which will be more efficient than checking in a list, or using try and except).

If you want a more complex CLI, with e.g. flags and specific value types, you should use something like argparse or click.

Community
  • 1
  • 1
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • @VigneshKalai if they wanted to comment, they would have – jonrsharpe Oct 22 '15 at 10:40
  • I commented just for future reference if someone wants to point the mistake and I would not be using `*sys.argv[2:]` it causes error for this sample if more than two arguments are passed through command line – The6thSense Oct 22 '15 at 10:43
  • `number() takes exactly 1 argument (3 given) when this is given python test.py message 1 2 3` – The6thSense Oct 22 '15 at 10:46
  • 1
    @VigneshKalai yes, because the additional parameters *aren't supported*. In my view, getting a clear exception is better than silently ignoring subsequent parameters. – jonrsharpe Oct 22 '15 at 10:47
  • accepted I will just leave my comment to stay for the help of others – The6thSense Oct 22 '15 at 10:49
  • Very clear, thx for the explanation and the answer @jonrsharpe – Shapi Oct 22 '15 at 10:52