11

getattrユーザーが「デフォルト」の戻り値を指定できるようにする組み込み関数(など)の動作を模倣したいと考えています。私の最初の試みはこれを行うことでした

def myfunc(foo, default=None):
    # do stuff
    if (default is not None):
        return default
    raise SomeException()

問題は、ユーザーがNone戻り値になりたい場合、この関数が代わりに例外を発生させることです。2回目の試行:

def myfunc(foo, **kwargs):
    # do stuff
    if ('default' in kwargs):
        return kwargs['default']
    raise SomeException()

これは上記の問題に対処し、ユーザーが任意の値を指定できるようにしますが、ユーザーがdefault=bar関数呼び出しで常に指定しなければならないという煩わしさをもたらします。彼らは最後に提供することはできませんbar。同様に*args使用できますが、ユーザーがdefault=barその構文を好む場合は使用できません。

組み合わせて実行可能なソリューション*args**kwargs提供しますが、これには多大な労力がかかるように感じます。また、不適切な関数呼び出しをマスクする可能性もあります(例bar = myfunc(foo, baz, default=qux)) 。

def myfunc(foo, *args, **kwargs):
    # do stuff
    if (len(args) == 1):
        return args[0]
    if ('default' in kwargs):
        return kwargs['default']
    raise SomeException()

より簡単な解決策はありますか?(それが重要な場合はPython 3.2)

4

1 に答える 1

17

デフォルト値が設定されていないことを検出するには、番兵を使用する必要があります。

sentinel = object()

def func(someparam, default=sentinel):
    if default is not sentinel:
        print("You passed in something else!")

これが機能するのは、のインスタンスobject()が常に独自のメモリIDを持ちis、正確な値がそのまま残されている場合にのみTrueを返すためです。を含む他の値は、同じオブジェクトとして登録されませんNone

さまざまなPythonプロジェクトで、上記のトリックのさまざまなバリエーションが表示されます。次の番兵のいずれも機能します。

sentinel = []
sentinel = {}
于 2012-09-04T14:33:23.930 に答える