我有这样的定义
def bar(self, foo=None, bar=None, baz=None):
pass
我想确保foo,bar,baz中最多有一个通过。我能做到
if foo and bar:
raise Ex()
if foo and baz:
raise Ex()
....
但是有一些更简单的东西。
答案 0 :(得分:9)
怎么样:
initialisers = [foo, bar, baz]
if initialisers.count(None) < len(initialisers) - 1:
raise Ex()
它只计算有多少None
存在。如果他们都是None
或者只有一个不是那么好,否则会引发异常。
答案 1 :(得分:6)
x!=None
为非Nones返回True
(其数值为1
!),其中False
(其数值为0)表示Nones。所以,
sum(x!=None for x in (foo, bar, baz))
是计算这些标识符中有多少绑定到非None值的最简单方法(并且您可以将其计数与1一样,就像其他答案一样,他们的获取计数的方式) 。这是一种非常通用的方法,而不是x!=None
你可以使用任何感兴趣的严格bool谓词;例如,如果你有一堆整数,并想知道它们中有多少有3
作为十进制表示的第一个数字,
sum(str(abs(x)).startswith('3') for x in (a, b, c, d, e))
也可以。
不要对“总结bool”感到不安:Python bool被明确定义为int的子类,恰好有两个具有特殊str / repr的实例,但其他行为与普通的0和1完全相同。有很好的实用性这种设计的原因和对bools进行算术运算的能力就是其中之一,所以请随意使用这种能力! - )
答案 2 :(得分:4)
尝试
count = sum(map(lambda x: 0 if x is None else 1, (foo, bar, baz)))
if count > 1:
raise Ex()
将None
变为0,将所有内容变为1,然后将所有内容汇总起来。
答案 3 :(得分:2)
我的答案更简短,我最喜欢的python功能 - 装饰器:
def single_keyword(func):
def single_keyword_dec(*args, **kw):
if len(kw) > 1:
raise Exception("More than one initializer passed: {0}".format(kw.keys()))
return func(*args, **kw)
return single_keyword_dec
@single_keyword
def some_func(self, foo=None, bar=None, baz=None):
print foo, bar, baz
some_func(object, foo=0)
some_func(object, foo=0, bar=0)
#result
0 None None
Traceback (most recent call last):
File "dec2.py", line 13, in <module>
some_func(object, foo=0, bar=0)
File "dec2.py", line 4, in single_keyword_dec
raise Exception("More than one initializer passed: {0}".format(kw.keys()))
Exception: More than one initializer passed: ['foo', 'bar']
如果您需要区分'foo','bar','baz'和其他一些关键字,您可以制作类似的装饰器,它可以接受要限制的关键字列表,并使用它如下:@single_keyword('foo', 'bar', 'baz')
< / p>
这样它的100%代码重用,不会反复输入相同的东西,并且你在函数中得到了合适的关键字,而不是一些模糊的字典。
答案 4 :(得分:1)
if len(filter(lambda x: x != None, locals().values())) > 1:
raise Exception()
编辑解决亚历克斯的观点。
答案 5 :(得分:-1)
喜欢这个。
def func( self, **kw ):
assert len(kw) == 1, "Too Many Arguments"
assert kw.keys[0] in ( 'foo', 'bar', 'baz' ), "Argument not foo, bar or baz"