2

I have a python file which contains the below code

test.py

def sum(a, b):
    print(a+b)

def final():
    print("Hello")
    sum(10, 9)


if __name__=="__main__":
    final()

Now when I run from the command line

python test.py

I get

Hello
19

Now I want to add a function say which will be called separately from the command line.How do I do it?So my updated code will be

def sum(a, b):
    print(a+b)

def say():
    print("Yes!!!")

def final():
    print("Hello")
    sum(10, 9)


if __name__=="__main__":
    final()

So now I want to call the function say seperately.I tried doing this

python test.py say

But it only outputs the previous result.How can I make this work?

Daniel
  • 11,332
  • 9
  • 44
  • 72
Souvik Ray
  • 2,899
  • 5
  • 38
  • 70
  • `say` will appear in your arguments, so test your arguments in the script. – Mark Setchell May 23 '18 at 07:58
  • @MarkSetchell I am sorry but I don't quite understand.Could you elaborate a bit? – Souvik Ray May 23 '18 at 08:01
  • 1
    Add a line before `final` that prints `sys.argv` and run your script with `python test.py say` and you'll see your program can detect the presence of `say` as a parameter. If it does, call `say`. – Mark Setchell May 23 '18 at 08:03

2 Answers2

2

Start the python interpreter on the command line from the directory where your source file is. Then you can do

from test import say
say()

Edit:

Based on the comments above, you could check sys.argv to find if the module was called with "say":

import sys

if __name__ == '__main__':
    if 'say' in sys.argv:
        say()
    else:
        final()

sys.argv is a list with all the arguments the module was called with so if you from the command line run

python test.py say foo bar

then

sys.argv = ['test.py', 'say', 'foo', 'bar']

inside your program.

Syntaxén
  • 465
  • 1
  • 8
  • 15
  • Is there any way to do it from the command line?Since I have a cron job that executes a command line query. – Souvik Ray May 23 '18 at 07:57
  • When the module is run from the command line, it's name will be '__main__', so as you have written your program in the question, it will call the final() function. The module will have another name only when it is imported somewhere else. I would go for @MarkSetchell's suggestion and look in sys.args, which is a list of all arguments that the module was called with from the command line. – Syntaxén May 23 '18 at 08:17
2

Your code will have to know what to do, somehow. This leaves you two alternatives:

1. The code will decide what to do based on external information:

a. Read a variable from the environment:

import os

if os.environ.get('TERM') == 'xterm-256color':
    say()
else:
    final()

You may set environment variables before calling the script as in:

# set the variable
$ export VARIABLE=VALUE

# Python will recognize it:
$ python -c "import os; print(os.environ.get('VARIABLE'))"
$ VALUE

b. Roll a dice:

from random import randint

if randint(0,6) > 3:
    say()
else:
    final()

2. You will tell the code what to do:

a. Check sys.argv (see other answers).

b. Recommended: Use the argparse library to parse commands:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--say", help="If say, then say", action="store_true")
args = parser.parse_args()

if args.say:
   say()
else:
   final()

Now, from the command line run: python test.py --say

Argparse is part of the standard python library, has excellent documentation, is easy to use and read, and (in my opinion) is very flexible.

c. For somewhat larger scripts / projects, use setuptools entrypoints: Details on this related question and this post.

Daniel
  • 11,332
  • 9
  • 44
  • 72
  • I think your answer would be more useful if you explained for 1a) *how* you might set the environment variable in advance of running the script, and if at 2) you explained *why* it is recommended to introduce a new dependence on `argparse` – Mark Setchell May 23 '18 at 10:11