Я хочу создать функцию быстрого доступа для создания объекта вопроса в моих тестах django.
Я не люблю постоянно набирать что-то вроде new_q(timedelta(minutes=1))
, и я хочу написать это timedelta только один раз и иметь возможность передавать его аргументы в удобной форме функции new_q
.
Есть ли какое-нибудь питоническое однострочное решение для этого, в котором мне не нужно захватывать kwargs в переменную, а затем создавать объект timedelta в новой строке?
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)
Применение:
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 = '', offset=timedelta(**kwargs)):
Это создает значение по умолчанию для offset
, и это значение создается путем вызова timedelta(**kwargs)
для всего, что находится в kwargs
во время определения функции. (Что, вероятно, вообще ничего, так что вы получите NameError
.)
Вам нужно что-то вроде этого:
def new_q(question_text = '', offset=None, **kwargs):
if offset is None:
offset = timedelta(**kwargs)
Теперь вы вызываете timedelta
при вызове функции, а не когда она определена, и используете значение kwargs
, переданное в функцию, а не то значение, которое переменная имеет во время определения функции.
Вы, конечно, можете добавить некоторую обработку ошибок, так что TypeError
, который вы получаете для аргумента неизвестного ключевого слова, упоминает new_q
вместо timedelta
, и поэтому будет ошибкой указывать и offset
, и minutes
, и так далее.
Кроме того, если кто-то не передает ни offset
, ни какие-либо другие аргументы ключевого слова, это создаст timedelta()
- пустой timedelta
(0 секунд). Это то, что вы хотите?
@tgwtdt ты божья коровка?
@AlexHall ну это неловко
Важная вещь, которую следует извлечь из этого ответа, - это то, что значения по умолчанию оцениваются один раз и только один раз, во время определения.
def new_q(question_text = '', **kwargs):
time = timezone.now() + timedelta(**kwargs)
...
Это все еще довольно кратко: здесь дважды упоминается kwargs
, но нет offset
или чего-то еще.
@tgwtdt Вы хотите, чтобы люди могли передавать
offset=myoffset
, если у них уже естьtimedelta
, которые они хотят использовать? Если нет, просто отбросьтеoffset=None
иif
и просто запишитеoffset=timedelta(**kwargs)
в функции.