Python – передать именованные аргументы объекту функции

Мне позвонили по поводу устаревших параметров в веб-приложении. Я видел этот пост...

wtforms+flask сегодняшняя дата в качестве значения по умолчанию

... что было на высоте.

Значение поля по умолчанию устанавливалось при запуске веб-сервера. Это было легко проверить. Пара операторов печати в файле, и это было доказано.

Итак, теперь вопрос старшего инженера-программиста: «Как передать параметры?».

Итак, тогда...

myfunc(offset=3):
    .... some code

fromdate = fields.DateField('From Date', default=myfunc, validators=[validators.required()])

Но старший инженер-программист хотел бы иметь возможность встраивать аргументы в функцию во время ее назначения, например...

fromdate = fields.DateField('From Date', default=myfunc(-10), validators=[validators.required()])

... но не вызывая его немедленно. По сути, сохранение объекта функции и его аргументов без их выполнения, по-прежнему откладывая, чтобы код выполнялся при загрузке страницы, а не при запуске сервера.

На данный момент у нас есть две идеи.

  1. Старший инженер-программист рассматривает возможность обернуть метод вокруг метода. Итак, есть один основной метод, а затем куча других, зависящих от сценария, таких как myfuncminus10.
  2. Я думаю о лямбда-выражениях. Что-то вроде myfunc = lambda :datetime.now().date() - timedelta(days=365) Это определенно даст ожидаемый результат, но может привести к большому количеству копирования и вставки одного и того же кода.

Как лучше всего подойти к этому? Я полагаю, что есть довольно хороший способ, который не является ни одним из двух способов, которые я только что описал, и мы просто еще не знаем его.


person MrGoodfix    schedule 29.04.2016    source источник
comment
В течение минуты 3 ответа для functools.partial. я свой удалю.   -  person AKS    schedule 29.04.2016
comment
См. также: Частичное применение и Каррирование   -  person Lukas Graf    schedule 29.04.2016


Ответы (3)


Вы описываете существующую функцию — functools.partial:

from functools import partial

fromdate = fields.DateField('From Date', default=partial(myfunc, offset=-10), validators=[validators.required()])
person schwobaseggl    schedule 29.04.2016
comment
Потрясающие! спасибо за голову. Как это соотносится с лямбда-выражением, опубликованным Алексом Холлом ниже? - person MrGoodfix; 03.05.2016
comment
Есть некоторые тонкие различия (связанные с ранним/поздним связыванием/фреймом стека) (читайте, например, эту ветку для справки), но в данном случае я совершенно уверен, что вы можете использовать любой из них, не заметив разницы. - person schwobaseggl; 04.05.2016
comment
чувак, я бы хотел, чтобы был способ отметить несколько ответов как ответ - person MrGoodfix; 06.05.2016

Вы можете легко создать вызываемый объект без аргументов, просто добавив lambda:, то есть:

fromdate = fields.DateField('From Date', default=lambda: myfunc(-10), validators=[validators.required()])
person Alex Hall    schedule 29.04.2016
comment
Ха-ха забавно! похоже, я проглядел очевидный вариант. Есть ли какое-либо преимущество в том, чтобы делать это таким образом, по сравнению с использованием partial из functools, указанного выше? - person MrGoodfix; 03.05.2016
comment
Я лично нахожу это гораздо более читаемым, но другие, похоже, не согласны. - person Alex Hall; 04.05.2016
comment
чувак, я бы хотел, чтобы был способ отметить несколько ответов как ответ - person MrGoodfix; 06.05.2016

Похоже, вы могли бы использовать functools.partial:

>>> from functools import partial
>>> fromdate = fields.DateField('From Date', default=partial(myfunc, 10), validators=[validators.required()])

Дополнительная информация: https://docs.python.org/2/library/functools.html#functools.partial

person JoseKilo    schedule 29.04.2016