2016-10-21 21 views
0

名前付き引数のうちの1つだけを必要とする関数をうまく定義するにはどうすればよいですか?引数の相互排他性を強制する方法は?

def foo (**args): 
    if len(args) != 1: 
     raise ValueError("foo: too many or too few args",args) 
    arg,val = args.iteritems().next() 
    if arg == "a": 
     return something for a 
    if arg == "b": 
     return something for b 
    if arg == "c": 
     return something for c 
    raise ValueError("foo: unknown argument",arg,val) 

ノートよりも優れ

def foo (a=None, b=None, c=None): 
    if a and b in None and c is None: 
     return something for a 
    if a in None and b and c is None: 
     return something for b 
    if a is None and b in None and c: 
     return something for c 
    raise ValueError("foo requires one and only one of a, b and c",a,b,c) 

何かがまたそれだけでなく、第二のバージョンは最初のものよりも短くなっていない、それはまた、許容可能な引数のリストを検出してからpylintのような静的チェッカーを防ぐことができます。

+0

@JasonHeineが、これは "正確に1指定" です。 – Barmar

+0

これは、外部ユーザーとコードの開発の両方にとって悪いデザインのようです。 3つの異なる機能を作ってみませんか? –

+0

@AlexHall:私は実際に自分自身について疑問に思っています... – sds

答えて

1

このコードでは、どのパラメータがNoneではないかを簡単に知ることができます。

def foo(a=None, b=None, c=None): 
    paramDict = {'a': a, 'b' : b, 'c' : c} 
    matches = [x for x in paramDict if paramDict[x] != None] 
    if len(matches) != 1: 
     raise ValueError("foo requires one and only one of a, b and c") 
    else: 
     print("parameter %s == %s" % (matches[0], paramDict[matches[0]])) 
2

かなり簡単、あなただけNone秒を数える: "指定された少なくとも1引数" だ

if [a,b,c].count(None) != 2: 
    raise ValueError("foo requires exactly one argument among a,b and c.") 
関連する問題