Какой самый питонический способ передать kwargs в этой функции?

Я хочу создать функцию быстрого доступа для создания объекта вопроса в моих тестах 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?')
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
148
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

То, что вы пытаетесь здесь написать, не имеет смысла:

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 Вы хотите, чтобы люди могли передавать offset=myoffset, если у них уже есть timedelta, которые они хотят использовать? Если нет, просто отбросьте offset=None и if и просто запишите offset=timedelta(**kwargs) в функции.

abarnert 01.05.2018 20:06

@tgwtdt ты божья коровка?

Alex Hall 01.05.2018 20:06

@AlexHall ну это неловко

DeepSpace 01.05.2018 20:09

Важная вещь, которую следует извлечь из этого ответа, - это то, что значения по умолчанию оцениваются один раз и только один раз, во время определения.

DeepSpace 01.05.2018 20:11
Ответ принят как подходящий
def new_q(question_text = '', **kwargs):
    time = timezone.now() + timedelta(**kwargs)
    ...

Это все еще довольно кратко: здесь дважды упоминается kwargs, но нет offset или чего-то еще.

Другие вопросы по теме