首页 > 解决方案 > 仅在需要时传递参数

问题描述

例如,我有一个函数f和一个变量a=1。有时f需要a,我想打电话f(a=a),而其他时候f没有参数。我该如何处理?

当我尝试调用时f(a=a)(期望它会默默地忽略a未使用的情况f),我得到以下类型错误:

f got an unexpected keyword argument 'a'

编辑

我想实现一个函数g,给定:

def f1(a):
    return a

def f2():
    return 1

我们有:

g(f1, a) == a
g(f2, a) == 1

标签: pythonpython-3.xfunctional-programming

解决方案


使用关键字字典f

def f(**kwargs):
    if 'a' in kwargs:
        print("a passed with value {}".format(kwargs['a']))
    else:
        print('a not passed')

f(a=12)
f()

印刷:

a passed with value 12
a not passed

它使参数测试/检索完全手动。你可以做任何你想做的事,它可以推广到几个论点。

这也禁止将参数作为位置传递,f(12)这在您的情况下可能是一件好事。

>>> f(12)
Traceback (most recent call last):
TypeError: f() takes 0 positional arguments but 1 was given

缺点是调用者不能依赖参数名称来知道要传递什么。要么创建一个文档字符串,要么人们将不得不阅读代码/猜测......

现在将其应用于您的编辑,我必须说哪种改变了问题。所以f2不能改变,在这种情况下,工作必须在包装函数中完成:

def f1(a):
    return a
def f2():
    return 1

def g(f,arg):
    try:
        return f(a=arg)
    except TypeError:
        return f()

a=12
print(g(f1, a))
print(g(f2, a))

印刷:

12
1

所以“最好请求宽恕而不是许可”:如果我们得到 a TypeError(当函数不知道参数时引发),我们只是在没有参数的情况下调用函数。缺点是如果第一个函数返回 a TypeError,我们无法知道它是参数还是函数内部。

一种解决方法是检查错误消息,如果错误消息与参数有关,则仅调用不带参数的函数:

def g(f,arg):
    try:
        return f(a=arg)
    except TypeError as e:
        if "unexpected keyword" in str(e):
            return f()
        else:
            raise e  # another TypeError, let it pass

推荐阅读