I have this code:
def hello():
return 'Hi :)'
How would I run this directly from the command line?
python -c 'from myfile import hello; hello()'
where myfile
must be replaced with the basename of your Python script. (E.g., myfile.py
becomes myfile
).
However, if hello()
is your "permanent" main entry point in your Python script, then the usual way to do this is as follows:
def hello():
print "Hi :)"
if __name__ == "__main__":
hello()
This allows you to execute the script simply by running python myfile.py
or python -m myfile
.
Some explanation here: __name__
is a special Python variable that holds the name of the module currently being executed, except when the module is started from the command line, in which case it becomes "__main__"
.
add this snippet to the bottom of your script
def myfunction():
...
if __name__ == '__main__':
globals()[sys.argv[1]]()
You can now call your function by running
python myscript.py myfunction
This works because you are passing the command line argument (a string of the function's name) into locals
, a dictionary with a current local symbol table. The parantheses at the end will make the function be called.
update: if you would like the function to accept a parameter from the command line, you can pass in sys.argv[2]
like this:
def myfunction(mystring):
print(mystring)
if __name__ == '__main__':
globals()[sys.argv[1]](sys.argv[2])
This way, running python myscript.py myfunction "hello"
will output hello
.
I wrote a quick little Python script that is callable from a bash command line. It takes the name of the module, class and method you want to call and the parameters you want to pass. I call it PyRun and left off the .py extension and made it executable with chmod +x PyRun so that I can just call it quickly as follow:
./PyRun PyTest.ClassName.Method1 Param1
Save this in a file called PyRun
#!/usr/bin/env python
#make executable in bash chmod +x PyRun
import sys
import inspect
import importlib
import os
if __name__ == "__main__":
cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
if cmd_folder not in sys.path:
sys.path.insert(0, cmd_folder)
# get the second argument from the command line
methodname = sys.argv[1]
# split this into module, class and function name
modulename, classname, funcname = methodname.split(".")
# get pointers to the objects based on the string names
themodule = importlib.import_module(modulename)
theclass = getattr(themodule, classname)
thefunc = getattr(theclass, funcname)
# pass all the parameters from the third until the end of
# what the function needs & ignore the rest
args = inspect.getargspec(thefunc)
z = len(args[0]) + 2
params=sys.argv[2:z]
thefunc(*params)
Here is a sample module to show how it works. This is saved in a file called PyTest.py:
class SomeClass:
@staticmethod
def First():
print "First"
@staticmethod
def Second(x):
print(x)
# for x1 in x:
# print x1
@staticmethod
def Third(x, y):
print x
print y
class OtherClass:
@staticmethod
def Uno():
print("Uno")
Try running these examples:
./PyRun PyTest.SomeClass.First
./PyRun PyTest.SomeClass.Second Hello
./PyRun PyTest.SomeClass.Third Hello World
./PyRun PyTest.OtherClass.Uno
./PyRun PyTest.SomeClass.Second "Hello"
./PyRun PyTest.SomeClass.Second \(Hello, World\)
Note the last example of escaping the parentheses to pass in a tuple as the only parameter to the Second method.
If you pass too few parameters for what the method needs you get an error. If you pass too many, it ignores the extras. The module must be in the current working folder, put PyRun can be anywhere in your path.
Let's make this a little easier on ourselves and just use a module...
Try: pip install compago
Then write:
import compago
app = compago.Application()
@app.command
def hello():
print "hi there!"
@app.command
def goodbye():
print "see ya later."
if __name__ == "__main__":
app.run()
Then use like so:
$ python test.py hello
hi there!
$ python test.py goodbye
see ya later.
Note: There's a bug in Python 3 at the moment, but works great with Python 2.
Edit: An even better option, in my opinion is the module fire by Google which makes it easy to also pass function arguments. It is installed with pip install fire
. From their GitHub:
Here's a simple example.
import fire
class Calculator(object):
"""A simple calculator class."""
def double(self, number):
return 2 * number
if __name__ == '__main__':
fire.Fire(Calculator)
Then, from the command line, you can run:
python calculator.py double 10 # 20
python calculator.py double --number=15 # 30
Interestingly enough, if the goal was to print to the command line console or perform some other minute python operation, you can pipe input into the python interpreter like so:
echo print("hi:)") | python
as well as pipe files..
python < foo.py
*Note that the extension does not have to be .py for the second to work. **Also note that for bash you may need to escape the characters
echo print\(\"hi:\)\"\) | python
If you install the runp package with pip install runp
its a matter of running:
runp myfile.py hello
You can find the repository at: https://github.com/vascop/runp
I had a requirement of using various python utilities (range, string, etc.) on the command line and had written the tool pyfunc specifically for that. You can use it to enrich you command line usage experience:
$ pyfunc -m range -a 1 7 2
1
3
5
$ pyfunc -m string.upper -a test
TEST
$ pyfunc -m string.replace -a 'analyze what' 'what' 'this'
analyze this
We can write something like this. I have used with python-3.7.x
import sys
def print_fn():
print("Hi")
def sum_fn(a, b):
print(a + b)
if __name__ == "__main__":
args = sys.argv
# args[0] = current file
# args[1] = function name
# args[2:] = function args : (*unpacked)
globals()[args[1]](*args[2:])
python demo.py print_fn
python demo.py sum_fn 5 8
It is always an option to enter python on the command line with the command python
then import your file so import example_file
then run the command with example_file.hello()
This avoids the weird .pyc copy function that crops up every time you run python -c etc.
Maybe not as convenient as a single-command, but a good quick fix to text a file from the command line, and allows you to use python to call and execute your file.
Something like this: call_from_terminal.py
# call_from_terminal.py
# Ex to run from terminal
# ip='"hi"'
# python -c "import call_from_terminal as cft; cft.test_term_fun(${ip})"
# or
# fun_name='call_from_terminal'
# python -c "import ${fun_name} as cft; cft.test_term_fun(${ip})"
def test_term_fun(ip):
print ip
This works in bash.
$ ip='"hi"' ; fun_name='call_from_terminal'
$ python -c "import ${fun_name} as cft; cft.test_term_fun(${ip})"
hi
Below is the Odd_Even_function.py file that has the definition of the function.
def OE(n):
for a in range(n):
if a % 2 == 0:
print(a)
else:
print(a, "ODD")
Now to call the same from Command prompt below are the options worked for me.
Options 1 Full path of the exe\python.exe -c "import Odd_Even_function; Odd_Even_function.OE(100)"
Option 2 Full path of the exe\python.exe -c "from Odd_Even_function import OE; OE(100)"
Thanks.
Use the python-c tool (pip install python-c) and then simply write:
$ python-c foo 'hello()'
or in case you have no function name clashes in your python files:
$ python-c 'hello()'
First you have to call the function as they told you or the founction will display nothing in the output, after that save the file and copy the path of the file by right click to the folder of the file and click on"copy file" then go to terminal and write: - cd "the path of the file" - python "name of the file for example (main.py)" after that it will display the output of your code.
print "Hi :)"
instead ofreturn 'Hi :)'
. – Tamás