2

デフォルト値がlikefunctionのブール値引数を取る関数 ( と呼ばれる) があるとします。Truedef function(argument1 = True)

resolveArgここで、この関数を使用して、既存のインフラストラクチャで引数をチェックする別の関数 ( ) の出力を使用して引数を指定するとします。このresolveArgメソッドは一般的に使用され、指定された関数 (例: ) の引数値が見つかった場合functionは関数の引数をそれに設定し、それ以外の場合は引数を に設定しますNone

引数がこの他の関数 ( ) によってfunction設定されている場合、引数のデフォルト値を使用するにはどうすればよいですか?NoneresolveArg

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

警告

あなたは、「Python で引数が None として指定されている場合に、引数にデフォルト値を使用する関数を取得する良い方法はありますか?」と尋ねました。

それは良いことではないので、良い方法はないと主張します。Noneこれは危険な行為です。値を期待する場所に渡されたという事実を合理的に検出したい場合に、厄介なエラーのケースを隠すことができます。この手法が広範囲に使用されているデバッグは恐ろしいものになる可能性があります。 細心の注意を払って使用してください。

可能な方法

例として提供するものよりも多くの機能で機能する一般的なソリューションが必要だと思います。この例Noneでは、引数値を単純にテストし、必要に応じて置き換えるのが最も簡単です。

一般的なケースを実行するデコレーターを作成できます。これは、inspect ツールボックスを使用して、引数のリスト全体の引数値をデフォルト値で計算し、それらがNone.

以下のコードは、いくつかの簡単なテスト ケースでアイデアを示しています*args, **kwargs。これらのケースをカバーするように拡張できます。デフォルトのない引数を通常どおり安全に扱います。

パイソンフィドル

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 に答える
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 に答える
0

function1 つの方法は、引数がTrueorの場合に同じ動作をすることですNone

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