Reputation: 323
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?')
Upvotes: 1
Views: 214
Reputation: 365787
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?
Upvotes: 1
Reputation: 36033
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.
Upvotes: 2