kwargs in python executables - python

I'm trying to create a program that can be called from the command line and use keyword arguments in python 2.6. So far I've tried:
#!/usr/bin/python
def read(foo = 5):
print foo
return 0
if __name__ == '__main__'
read()
When I try to run this from the command line: ./test.py the program prints 5 as expected. Is there a way to use ./test.py foo=6? I want to preserve the keyword arguments.
It seems like a simple question, but I haven't found a good source for this.

python has built in library to help you achieve passing command line arguments to a script
argparse. THe usage is a little different then what you are describing in your question though...
On a basic level you can access all command line arguments by sys.argv, which will be a list of arguments
Sorry should have mentioned the python 2.6 library is called optparse

Something like this?
if __name__ == '__main__':
kwargs = dict(x.split('=', 1) for x in sys.argv[1:])
read(**kwargs)
That said, argparse and optparse are probably going to give you something more robust and more natural for someone used to the commandline. (Not to mention, supporting arguments of types other than string.)
Oh, and if what you're really after is just interactive use of your function, use the interactive interpreter; either python or ipython. You'd need to put the code into a file ending in .py and import it, then you could just call it.

A less usual, but very interesting alternative is docopt: a library that generates an argument parser from the help message that you write for your program (on github).

Related

Python - Execute program with parameters with file output

I am trying to use Python to run an executable (Windows 7) with parameters. I have been able to make the program run, but the amount of parameters I can use that will prove the Python script worked with parameters is limited. The best one is formatted like so:
-debugoutput debug.txt
I have tested this using a windows shortcut with an edited target and it works, it creates a debug output in the program directory.
Here is the code I am using:
import subprocess
args = [r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput debug.txt"]
subprocess.call(args)
This does run the program, but the debug output is not created. I have tried putting an "r" in front of the parameter but this made no difference. I assume it is a simple formatting error but I can't find any examples to learn from that are doing the same thing.
UPDATE:
Thanks for the answers everyone, all the same, simple formatting error indeed.
In-code definition results in invocation of shell command line:
C:\Users\MyName\LevelEditor\LevelEditor.exe "-debugoutput debug.txt"
As you can see, by merging -debugoutput debug.txt to single list element, you explicitly stated that space between them shouldn't be parsed as command line argument separator.
To achieve expected behavior put file name string as separate element to argument list.
[r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput", "debug.txt"]
As far as I know you need to split the arguments by the space, so your args would look like:
args = [r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput", "debug.txt"]
Does that work?
I do not know if it works, but
import subprocess
args = [r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput", "debug.txt"]
subprocess.run(args)
Following the docs

Pass output of a script to another script using sys.argv

I'm trying to take the output of one script and pass it using sys.argv to my python script.
The question I have is whether there's a way to accomplish this similar to
python runfile.py $(node parse.js)
For testing, runfile.py just consists of:
import sys
print sys.argv
But, as you might've guessed, that just logs ['runfile.py'].
Am I totally barking up the wrong tree here? If so, can someone explain or link to an explanation of how to pass the output of, say, a javascript file to a python script?
Edit: is there a way to mark the $(node parse.js) part as a separate argument that should be evaluated?
Instead of passing the output of node parse.js to your python script via command line arguments (sys.argv) you could use stdin and unix pipes:
node parse.js | python runfile.py
And edit runfile.py to look like:
import sys
print sys.stdin

Python script argument conditional

Is anyone able to tell me how to write a conditional for an argument on a python script? I want it to print "Argument2 Entered" if it is run with a second command line arguments such as:
python script.py argument1 argument2
And print "No second argument" if it is run without command line arguments, like this:
python script.py argument1
Is this possible?
import sys
if len(sys.argv)==2: # first entry in sys.argv is script itself...
print "No second argument"
elif len(sys.argv)==3:
print "Second argument"
There are many answers to this, depending on what exactly you want to do and how much flexibility you are likely to need.
The simplest solution is to examine the variable sys.argv, which is a list containing all of the command-line arguments. (It also contains the name of the script as the first element.) To do this, simply look at len(sys.argv) and change behaviour based on its value.
However, this is often not flexible enough for what people expect command-line programs to do. For example, if you want a flag (-i, --no-defaults, ...) then it's not obvious how to write one with just sys.argv. Likewise for arguments (--dest-dir="downloads"). There are therefore many modules people have written to simplify this sort of argument parsing.
The built-in solution is argparse, which is powerful and pretty easy-to-use but not particularly concise.
A clever solution is plac, which inspects the signature of the main function to try to deduce what the command-line arguments should be.
There are many ways to do this simple thing in Python. If you are interested to know more than I recommend to read this article. BTW I am giving you one solution below:
import click
'''
Prerequisite: # python -m pip install click
run: python main.py ttt yyy
'''
#click.command(context_settings=dict(ignore_unknown_options=True))
#click.argument("argument1")
#click.argument("argument2")
def main(argument1, argument2):
print(f"argument1={argument1} and argument2={argument2}")
if __name__ == '__main__':
main()
Following block should be self explanatory
$ ./first.py second third 4th 5th
5
$ cat first.py
#!/usr/bin/env python
import sys
print (len(sys.argv))
This is related to many other posts depending upon where you are going with this, so I'll put four here:
What's the best way to grab/parse command line arguments passed to a Python script?
Implementing a "[command] [action] [parameter]" style command-line interfaces?
How can I process command line arguments in Python?
How do I format positional argument help using Python's optparse?
But the direct answer to your question from the Python docs:
sys.argv -
The list of command line arguments passed to a Python script. argv[0] is the script name (it is operating system dependent whether this is a full pathname or not). If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'. If no script name was passed to the Python interpreter, argv[0] is the empty string.
To loop over the standard input, or the list of files given on the command line, see the fileinput module.

run python command line arguments in shell script

I have a script which takes in few arguments
./hal --runtest=example
where example = /home/user/example.py
how can I pass these arguments in shell script?
I'm having trouble figuring out what you're asking, but assuming your question is "How can a shell script pass dynamic arguments to a command that happens to be written in Python" and you are using a Bourne-family shell (very likely), the simplest correct answer would be
example=/home/user/example.py
./hal "--runtest=$example"
The shell will resolve the quoting and the script will see --runtest=/home/user/example.py without breaking if you later decide to pass in a path containing spaces.
Take a look a the following:
http://lowfatlinux.com/linux-script-variables.html
It is Bash specific though and as per comments above not sure which shell you're using.
Here you'll find all you need in terms of how to pass an argument to a shell script.

How to parse command line arguments in Python? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What's the best way to grab/parse command line arguments passed to a Python script?
I would like to be able to parse command line arguments in my Python 2.6 program.
Ideally, I want to be able to handle these cases:
# Show some help
./myprogram --help
# These are equivalent
./myprogram --block=1
./myprogram -b 1
# This means verbose, and twice as verbose:
./myprogram -v
./myprogram -vv
Check out the argparse module (or optparse for older Python versions).
Note that argparse/optparse are newer, better replacements for getopt, so if you're new to this they're the recommended option. From the getopt docs:
Note The getopt module is a parser for command line options whose API is designed to be familiar to users of the C getopt() function. Users who are unfamiliar with the C getopt() function or who would like to write less code and get better help and error messages should consider using the argparse module instead.
Python has argument processing built in, with the getopt module.
It can handle long and short forms of arguments as well as "naked" and parameterised versions (--help versus --num=7).
For your specific use cases (with a little more), you'd probably be looking at something like:
opts,args = getopt.getopt(argv,"b:vVh",["block=", "verbose", "very-verbose", "help"])
I'm not sure off the top of my head if it allows multi-character single-hyphen variants like -vv. I'd just use -v and -V myself to make my life easier.
optfunc is an interesting little module. It's great if you want to quickly write a little script. For larger things I would go with argparse as others wrote.
A better option than that link is the modules OptParse or GetOpt, and depending on which version of Python you're using, the newest ones..2.7, and 3.1.2, have an even newer module built in. The documentation on the official python.org reference has a very informative set of documentation and examples for those modules. If you go to python.org and just do a quick search for OptParse or GetOpt, you'll have everything you need.
There might be a better way but I would just uses sys.argv and put in conditionals wherever needed i.e.
if '--v' or '--vv' in sys.argv :
print 'verbose message'

Categories