简体   繁体   中英

What is the most pythonic way to pass kwargs in this function?

I want to create a shortcut function for creating a question object in my django tests.

I don't like to type something like new_q(timedelta(minutes=1)) all the time and I want to write that timedelta only once and be able to pass it's arguments in a nice way to the new_q function.

Is there any pythonic one line solution to this in which I don't have to capture the kwargs to a variable and then create a timedelta object in a new line?

from datetime import timedelta
from django.utils import timezone


def new_q(question_text = '', offset=timedelta(**kwargs)):
    time = timezone.now() + offset
    return Question.objects.create(question_text=question_text, pub_date=time)

usage:

test1 = new_q(minutes=1)
test2 = new_q('yo?', seconds=1)
test2 = new_q(question_text = 'maw?', hours=11)
test2 = new_q(question_text = 'maw?')
test2 = new_q('yo?')
def new_q(question_text = '', **kwargs):
    time = timezone.now() + timedelta(**kwargs)
    ...

This is still pretty concise: it mentions kwargs twice, but there's no offset or anything else extra.

What you're trying to write here doesn't quite make sense:

def new_q(question_text = '', offset=timedelta(**kwargs)):

This creates a default value for offset , and that value is created by calling timedelta(**kwargs) on whatever happens to be in kwargs at the time the function is defined. (Which is probably nothing at all, so you get a NameError .)

What you want is something like this:

def new_q(question_text = '', offset=None, **kwargs):
    if offset is None:
        offset = timedelta(**kwargs)

Now you're calling timedelta when the function is called, rather than when it's defined, and using the value of kwargs passed into the function, rather than whatever value that variable has at function definition time.

You could of course add some error handling, so the TypeError you get for an unknown keyword argument mentions new_q instead of timedelta , and so that it's an error to specify both offset and minutes , and so on.

Also, if someone passes neither offset nor any other keyword arguments, this will create a timedelta() —which is an empty timedelta (0 seconds). Is that what you want?

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