带有可变参数的函数参数,避免 `if arg is None` 构造

Function argument with mutables, avoid `if arg is None` construct

有没有办法避免像下面这样的重复代码?想象 20 个其他函数采用默认值的可变参数。 每次检查 None 的参数,每次都在 if 分支中分配默认值。 将默认值放在函数签名中不起作用,因为 python 会在第一次调用函数时缓存值。

import datetime as dt

def dt_to_str(dtime: dt.datetime = None):
    if dtime is None:
        dtime = dt.datetime.now()

    return dtime.strftime("%c")


if __name__ == '__main__':
    print(dt_to_str())

我认为在大多数情况下,if arg is None: arg = ... 语法是最好的解决方案。但是如果你真的被它打扰了,这里有一个装饰器,它适用于单参数函数:

from functools import wraps

def default_argument(arg_factory):
    def decorator(f):
        @wraps(f)
        def wrapped(arg=None):
            if arg is None:
                arg = arg_factory()
            return f(arg)
        return wrapped
    return decorator

下面的用法示例:您可以传递对现有函数的引用,或传递 lambda.

import datetime as dt

@default_argument(dt.datetime.now)
def dt_to_str(dtime):
    return dtime.strftime('%c')

print(dt_to_str())
# Mon Oct 25 00:16:03 2021

@default_argument(lambda: [])
def thing_with_list(lst):
    return lst + [123]

print(thing_with_list())
# [123]