简体   繁体   中英

Making parameters (from Bash) nonoptional in Python

I'm pretty much a complete newbie when it comes to Python, and googling this leads to a lot of information about parameters... but not this specific question.

But here's the question: Is there an easy way to make a Python script require a variable when called from outside the script (eg Bash)? I realize I can just test on sys.argv, but it really seems like a clunky solution.

For example, could I construct this script so sys.argv[1] has to be passed to use the script without doing tests on it here?:

#!/usr/bin/env python
import string
import random
import sys

def RandomString(length=6):
    x=''.join(random.choice(string.ascii_uppercase) for i in range(length))
    return x

random.seed(sys.argv[1])
y=RandomString()
print y

Use the argparse module. You can define positional arguments that are required, and it will return an error if that argument is not included.

parser = argparse.ArgumentParser()
parser.add_argument('RandomSeed')
args = parser.parse_args()

random.seed(args.RandomSeed)

Usage of the above to lines from bash would be something like:

python main.py thisisarandomstring

Argparse is a nice way to parse your arguments for a command line application(and is a preferred, or good avenue to take when you make a command line app). It automatically generates you some help pages and other documentation, and generates appropriate errors without you having to do all the overehead yourself.

Check out this link for a pretty nice tutorial.

  • Argparser is not safe. "Argparse has built-in magic behavior to guess if something is an argument or an option." "Argparse currently does not support disabling of interspearsed arguments." Ref: http://click.pocoo.org/3/why/
  • You should always check argv because that is what is going to be used in your later code. Avoiding it seems nonsensical.

An answer without running "tests" on argv the best I know how to. At least here we are not looking at argv[1] :


#!/usr/bin/env python
import sys

if len(sys.argv) == 1:
    print 'not read in...exiting'
    exit()
print 'read in no problem'

Here's one possible solution with argparse , that will allow any string as a first argument. It's got two serious problems though: you can't define any optional arguments, which leads to the need to disable the -h/--help option. The technique for disabling options is a bit of a hack. Looking at the source, it's not enough to set prefix_chars to an empty string, but a tuple whose first element is an empty string. or maybe just an empty sequence. There might be some other issues as well.

from argparse import ArgumentParser
p = ArgumentParser(add_help=False, prefix_chars=("",))
p.add_argument("randomseed")

args = p.parse_args()

random.seed(args.randomseed)

Then a call like

python main.py -foo

would set args.randomseed to the string -foo .

Given all this, I think you will just have to accept you'll have to verify in-script that sys.argv has at least one command-line argument, since there is no better way to have bash check for you.

try:
    randomseed = sys.argv[1]
except IndexError:
    # Do something here; I suggest just using a value that 
    # lets random.seed() invoke its default, no-argument behavior
    randomseed = None

This an extremely rich resource you should read about this: https://stackoverflow.com/a/4118133/3767980

For below, I am just checking to see if the string has anything in it. If it is empty (not read in) it will print to the terminal and exit.

#!/usr/bin/env python
import string
import random
import sys

# testing argv[1]

if 'argv[1]' in locals():
    print 'read in, no problem'
else:
    print 'not read in...exiting'
    exit()
fi

References:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM