2

假设我有一个函数(称为function),它接受一个默认值为Truelike的布尔参数def function(argument1 = True)

现在假设我想使用这个函数,使用另一个函数 ( resolveArg) 的输出来指定它的参数,该函数检查现有基础设施中的参数。此resolveArg方法通常使用,如果它可以找到发往给定函数(例如function)的参数值,则将函数参数设置为它,否则将参数设置为None

function如果它的参数被None这个其他函数( )设置为,我怎样才能使用它的参数的默认值resolveArg

def resolveArg(argName = None):
    if argName in self.conf._argdict:
        return(self.conf._argdict[argName].value)
    else:
        return(None)

def function(argument1 = True)
    if argument1 is True:
        return(True)
    elif argument1 is False:
        return(False)
    else:
        raise(Exception)

function(argument1 = resolveArg("red"))
4

4 回答 4

1

我以前没有见过这种问题,所以可能有一种方法可以改进你的逻辑并省略这个功能。

然而,有一种方法可以通过使用模块"inspect"对 Python 中的代码进行自省。

一个示例用法是:

>>> def a(q=5):
...  if q is None:
...   return dict(inspect.getmembers(a))['func_defaults'][0]
...  return q
...
>>> a()
5
>>> a(None)
5

这样做的问题是“func_defaults”返回一个列表,如果您有多个参数函数并且作为一个整体使过程容易出错,这很不方便。

于 2015-02-26T09:35:06.133 回答
1

警告

您要求“在 Python 中将参数指定为 None 时,让函数使用其默认值作为参数的好方法?”

我会争辩说没有好的方法,因为这不是一件好事。这是一件有风险的事情——它可以掩盖令人讨厌的错误情况,在这些情况下,您可能合理地想要检测None在您期望值的地方传递的事实。在广泛使用这种技术的地方进行调试可能会很糟糕。 使用时要格外小心。

可能的方法

我猜你想要一个通用的解决方案,它可以用于比你作为示例提供的功能更多的功能。在示例情况下 - 您最容易在参数值中简单地测试并None在必要时替换它。

您可以编写一个装饰器来处理一般情况,它将使用检查工具箱来计算具有默认值的参数列表中的参数值,如果它们是None.

下面的代码通过一些简单的测试用例演示了这个想法 - 这将起作用,但仅适用于*args, **kwargs当前构成的具有简单参数(not )的函数。可以对其进行增强以涵盖这些情况。它像往常一样安全地处理没有默认值的参数。

蟒蛇小提琴

import inspect

def none2defaultdecorator(thisfunc):
    (specargs, _, _, defaults) = inspect.getargspec(thisfunc)

    def wrappedfunc(*instargs):        
        callargs = inspect.getcallargs(thisfunc, *instargs)

        if len(specargs) != len(callargs):
             print "Strange - different argument count in this call to those in spec"
             print specargs
             print callargs

        for i,argname in enumerate(specargs[-len(defaults):]):
            try:
                if callargs[argname] == None:
                    callargs[argname] = defaults[i]
            except KeyError:
                # no local value for this argument - it will get the default anyway
                pass

        return thisfunc(**callargs)

    return wrappedfunc

#Decorate the funtion with the "None replacer".  Comment this out to see difference
@none2defaultdecorator            
def test(binarg = True, myint = 5):
    if binarg == True:
        print "Got binarg == true"
    elif binarg == False:
        print "Got binarg == false"
    else:
        print "Didn't understand this argument - binarg == ", binarg

    print "Argument values - binarg:",binarg,"; myint:",myint

test()
test(False)
test(True)
test(None)
test(None, None)
于 2015-02-26T12:45:19.887 回答
0

function如果参数是Trueor ,一种方法是给你相同的行为None

def function(arg=True):
    if arg in [True, None]:
        do_stuff()
    else:
        do_something_else()
于 2015-02-26T09:18:18.870 回答
0

可能你想修改你的一function点点实现如下:

def function(argument1 = None)
    if argument1 is None:
       argument1 = True        

    return argument1

如果您想了解更多关于默认函数参数为无的信息,您可能需要参考我的其他SO 答案

于 2017-07-04T22:57:54.827 回答