Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python arguments and keyword-arguments best practices

Tags:

python

django

I'm writing a Django App, where I am expecting to use many management.py commands. I like the idea of python functions having parameters with default values, where you define the param as:

def function(param1=value1)

So I'm writing my management commands such that you input as follows:

python manage.py createdb user=some_user db_name=some_name

So far as I can tell, management.py commands don't accept this type of argument list, so I've created a helper to do the following:

def process_args(args=None):
    kwargs = {}
    if not args:
        return kwargs
    for i in args:
        try:
            k,v = i.split('=')
            kwargs[k] = v
        except ValueError, ve:
            raise CommandError("Please Enter All Arguments as key=value.  e.g. user=admin")
    return kwargs

Is there a better way to do this?

like image 971
Sam Hammamy Avatar asked Mar 03 '12 04:03

Sam Hammamy


3 Answers

Updated: Per @rix, later versions of Django now use argparse, which should be preferred.

Original Answer:

I believe the standard approach here is to use optparse, which can hook into the existing option parsing Django uses already. The example from the 1.6 docs:

from optparse import make_option

class Command(BaseCommand):
    option_list = BaseCommand.option_list + (
        make_option('--delete',
            action='store_true',
            dest='delete',
            default=False,
            help='Delete poll instead of closing it'),
        )
    # ...

Now you have your command line arguments available in the options dictionary. The Python docs say optparse is deprecated, but I assume that the Django docs recommend it because it's what Django uses for its own management commands.

like image 169
nrabinowitz Avatar answered Nov 10 '22 12:11

nrabinowitz


Instead of rolling your own, you could use typical parameter style, and use something like argparse to parse it:

python manage.py createdb --user=some_user --db_name=some_name

You'd just define your argument parser and then pass the args argument to its parse_args() method.

like image 43
Amber Avatar answered Nov 10 '22 14:11

Amber


Docs over @ Python argparse are great, but for a quick copy paste answer to solve the original question (post Django 1.8) - here you go:

class Command(BaseCommand):

    def add_arguments(self, parser):
        parser.add_argument(
            '-something',
            action='store',
            dest='something',
            default=None,
            help="something",
        )

    def handle(self, *args, **options):
        print(options['something'])

python manage.py your_command -something='something'
like image 44
rix Avatar answered Nov 10 '22 12:11

rix