Динамические аргументы по умолчанию в функциях python

Мне нужны функции с аргументами по умолчанию, которые должны быть установлены во время выполнения функции (например, пустые списки, значения, полученные из других аргументов или данных, взятых из базы данных), и в настоящее время я использую следующий шаблон для решения этой проблемы:

def foo(bar, baz=None): baz = baz if baz else blar() # Stuff 

Где blar() дает правильное значение по умолчанию baz которое может измениться во время выполнения. Тем не менее, baz = baz if baz else ... линия поражает меня как неэлегантную. У кого-нибудь еще есть лучший способ избежать одноразовой привязки аргументов функции по умолчанию? Малые, кросс-платформенные библиотеки, устанавливаемые по протоколу pip, являются приемлемыми заменами.

  • Найти один файл из многих, содержащих нужную строку в Python
  • Кастинг из списка списков строк в список списков ints в python
  • Печать Объединение строк и чисел
  • IndexError: индекс индекса вне диапазона чтения / записи из / в файл
  • Строка отображения Python несколько раз
  • Поиск заголовка, который начинается с python?
  • Как очистить входной поток в python?
  • Как конструкторы производных классов работают в python?
  • 3 Solutions collect form web for “Динамические аргументы по умолчанию в функциях python”

    Нет, это в значительной степени. Обычно вы проверяете значение « is None чтобы вы могли безопасно передавать ложные значения, такие как 0 или "" и т. Д.

     def foo(bar, baz=None): baz = baz if baz is not None else blar() 

    Старомодным способом является два лайнера. Некоторые люди могут предпочесть

     def foo(bar, baz=None): if baz is None: baz = blar() 

    Быстрая и грязная реализация того, что может работать:

     class DynDefault(object): def __init__(self, callback): self.callback = callback def __call__(self): return self.callback() def dyn_default(func): def wrapper(*args, **kw): args = [arg() for arg in args if isinstance(arg, DynDefault) else arg] for k, v in kw.items(): if isinstance(v, DynDefault): kw[k] = v() return func(*args, **kw) return wrapper @dyn_default def foo(bar, baaz=DynDefault(blar)): # problem solved 

    Вы можете заменить

     baz = baz if baz else blar() 

    с

     baz = baz or blar() 

    если вы все еще довольны просто тестированием фальшивых значений вместо None .

    Python - лучший язык программирования в мире.