当前位置: 首页 > 知识库问答 >
问题:

如何检查可选功能参数是否设置

周健
2023-03-14

Python中是否有一种简单的方法可以检查可选参数的值是否来自其默认值,或者是因为用户在函数调用时显式设置了它?

共有3个答案

益炜
2023-03-14

下面的函数装饰器< code>explicit_checker为显式给出的所有参数创建了一组参数名。它将结果作为额外参数(< code>explicit_params)添加到函数中。只需在explicit_params中执行< code>'a '来检查参数< code>a是否显式给定。

def explicit_checker(f):
    varnames = f.func_code.co_varnames
    def wrapper(*a, **kw):
        kw['explicit_params'] = set(list(varnames[:len(a)]) + kw.keys())
        return f(*a, **kw)
    return wrapper

@explicit_checker
def my_function(a, b=0, c=1, explicit_params=None):
    print a, b, c, explicit_params
    if 'b' in explicit_params:
        pass # Do whatever you want


my_function(1)
my_function(1, 0)
my_function(1, c=1)
虞俊美
2023-03-14

很多答案都有完整信息的一小部分,所以我想把它们和我最喜欢的模式结合在一起。

如果缺省值是一个可变对象,那么您很幸运:您可以利用Python的缺省参数在函数定义时被评估一次这一事实(在最后一节的答案末尾有更多关于这方面的内容)

这意味着您可以使用< code>is轻松比较默认可变值,以查看它是作为参数传递还是默认保留,如以下示例中的函数或方法:

def f(value={}):
    if value is f.__defaults__[0]:
        print('default')
    else:
        print('passed in the call')

class A:
    def f(self, value={}):
        if value is self.f.__defaults__[0]:
            print('default')
        else:
            print('passed in the call')

现在,如果你的默认值应该是一个不可变的值(请记住,即使是字符串也是不可变的!),那就不那么优雅了,因为你不能利用这个技巧,但你仍然可以做一些事情,仍然利用可变类型;基本上,您在函数签名中放置了可变的“假”默认值,并在函数体中放置了所需的“真实”默认值。

def f(value={}):
    """
    my function
    :param value: value for my function; default is 1
    """
    if value is f.__defaults__[0]:
        print('default')
        value = 1
    else:
        print('passed in the call')
    # whatever I want to do with the value
    print(value)

如果你真正的缺省值是< code>None,但< code>None是不可变的,那就特别有趣了...您仍然需要显式使用一个可变参数作为函数默认参数,并在代码中切换到None。

或者,与@c-z suggestion类似,如果python文档不够:-),您可以在两者之间添加一个对象,使API更加明确(无需阅读文档);used_proxy_Default类实例是可变的,将包含您想要使用的实际默认值。

class Default:
    def __repr__(self):
        return "Default Value: {} ({})".format(self.value, type(self.value))

    def __init__(self, value):
        self.value = value

def f(default=Default(1)):
    if default is f.__defaults__[0]:
        print('default')
        print(default)
        default = default.value
    else:
        print('passed in the call')
    print("argument is: {}".format(default))

现在:

>>> f()
default
Default Value: 1 (<class 'int'>)
argument is: 1

>>> f(2)
passed in the call
argument is: 2

上述内容也适用于默认(无)。<

显然,上面的模式看起来比它们应该的要丑陋,因为所有的print只是为了显示它们是如何工作的。否则我发现它们足够简洁和可重复。

您可以编写一个修饰符来添加@dmg建议的_ call_

更多关于#1 python gotcha!,为了你自己的快乐而滥用上面。您可以通过执行以下操作来查看由于定义处的评估而发生的情况:

def testme(default=[]):
    print(id(default))

您可以运行< code>testme()任意多次,您总是会看到对同一个默认实例的引用(所以基本上您的默认实例是不可变的:-)。

请记住,在Python中只有3种可变的内置类型:setlistcript;其他一切-甚至字符串!-是不可变的。

相云
2023-03-14

不完全是。标准方法是使用用户不希望传递的默认值,例如< code>object实例:

DEFAULT = object()
def foo(param=DEFAULT):
    if param is DEFAULT:
        ...

通常,如果 Null 作为用户想要传递的值没有意义,则可以将其用作默认值。

另一种方法是使用< code>kwargs:

def foo(**kwargs):
    if 'param' in kwargs:
        param = kwargs['param']
    else:
        ...

然而,这过于冗长,并使您的函数更难使用,因为它的文档不会自动包含< code>param参数。

 类似资料:
  • 问题内容: 在Python中,有没有一种简单的方法来检查可选参数的值是否来自其默认值,或者是因为用户已在函数调用中显式设置了它? 问题答案: 很多答案都没有完整信息的一部分,因此我想将所有信息与我最喜欢的模式结合在一起。 默认值是一种类型 如果默认值是可变对象,那么您很幸运:您可以利用以下事实:在定义函数时,Python的默认参数将被评估一次(上一节答案末尾的更多信息) 这意味着您可以轻松地使用来

  • 问题内容: 在Objective-C中,当我有一个数组时 我想检查它是否不为空,我总是这样做: 这样一来,无需检查是否会因为这种情况将导致代码陷入错误,并且非空数组也会这样做。 但是,在Swift中,我偶然发现了一个可选数组: 而且我无法确定要使用哪种条件。我有一些选择,例如: 选项A:在相同条件下检查非用例和空用例: 选项B: 使用解除绑定数组: 选项C: 使用Swift提供的合并运算符: 我不

  • 问题内容: 我有一个管道脚本,可以使用和不使用参数。因此,我必须检查该参数是否可用。 我试过了,但这导致异常 还有另一种检查作业是否已参数化的方法吗? 问题答案: 较新的版本通过变量使参数可用。如果未定义该参数,则它将回退到配置的默认值(另请参见此处)。

  • 问题内容: 好吧,我是SQL的新手,我刚刚读到,存储过程始终返回一个值,确定该过程中的查询是否已成功执行是一种很好的做法。 所以我有一个带有select语句的简单存储过程,如果要执行,我想返回1,否则返回-1。 您能告诉我如何用SQL编写该条件吗? 如果有关系,我的数据库是MS SQL Server。 谢谢你。 问题答案: 使用输出参数返回成功状态以及Try..Catch块

  • 问题内容: 如何检查a 是否被选中? 问题答案: 使用isSelected方法。 您还可以使用ItemListener,以便在选中或取消选中它时收到通知。

  • 问题内容: 在我的代码中的某些情况下,只有在定义了该函数的情况下,我最终才调用该函数,否则我不应该调用该函数。我怎样才能做到这一点? 提出此问题的另一种方法可能是:如何确定函数是否在运行时定义,如果是,则调用。 问题答案: 尽管其他答复是有用的建议(,函数指针等),但是您 不能编译 引用不存在的函数的C ++代码。至少必须 声明 函数;如果不是,您的代码将无法编译。如果没有任何内容(编译单元,某些