我试图找到一种干净的方式来处理不同的,互斥的功能输入。我的想法是,我有一个返回4个值的函数(这些值通过数学方程式链接),当您输入4个值中的一个时,它将返回所有值。
目前该功能的工作原理如下:
#example relations are simply: b=1+a, c=0.5*a, d=sqrt(a)
def relations(v, vtype="a"):
if vtype=="a":
a = v
elif vtype=="b":
a = v - 1
elif vtype=="c":
a = 2 * v
elif vtype=="d":
a = v ** 2
b = 1 + a
c = 0.5 * a
d = a ** 0.5
return a,b,c,d
用户通过字符串vtype指定输入变量是什么,并返回所有值。用户不可能输入多个不同的输入值(这将是多余的,因为可以从一个输入值确定所有未知数)。
有更干净和pythonic的方法吗?用字符串指定输入变量当前感觉非常脏。
提前致谢!
答案 0 :(得分:2)
您可以使用变量关键字参数:
def relations(**kwargs):
if 'a' in kwargs:
a = kwargs['a']
elif 'b' in kwargs:
a = kwargs['b'] - 1
elif 'c' in kwargs:
a = kwargs['c'] * 2
elif 'd' in kwargs:
a = kwargs['d'] ** 2
else:
raise TypeError('missing an argument')
b = 1 + a
c = 0.5 * a
d = a ** 0.5
return a, b, c, d
然后使用命名参数:
relations(a=2)
relations(b=4)
relations(c=9)
relations(d=0)
答案 1 :(得分:2)
避免许多if
- elif
的常用方法是构建函数字典:
def relations(v, vtype='a'):
functions = {
'a': lambda x: x, 'b': lambda x: x-1,
'c': lambda x: x * 2, 'd': lambda x: x**2
}
a = functions[vtype](v)
b = 1 + a
c = 0.5 * a
d = a ** 0.5
return a,b,c,d
如果此功能不是瓶颈,您可以避免使用lambda
,只需执行以下操作:
values = {'a': v, 'b': v-1, 'c': v * 2, 'd': v**2}
a = values[vtype]
如果您不喜欢在函数签名中使用vtype
,可以使用单个**kwargs
参数:
def relations(**kwargs):
if len(kwargs) != 1 or not set('abcd').intersection(kwargs):
raise ValueError('Invalid parameters')
vtype, v = kwargs.popitem()
functions = {
'a': lambda x: x, 'b': lambda x: x-1,
'c': lambda x: x * 2, 'd': lambda x: x**2
}
a = functions[vtype](v)
b = 1 + a
c = 0.5 * a
d = a ** 0.5
return a,b,c,d
然后将其称为:
relations(a=...)
relations(b=...)
答案 2 :(得分:1)
您可以将vtypes定义为函数,并将函数作为参数传递
def a(v):
return v
def b(v):
return v-1
def c(v):
return 2*v
def d(v):
return v**2
def relations(v, vtype=a):
value_a = vtype(v)
value_b = 1 + value_a
value_c = 0.5 * value_a
value_d = value_a ** 0.5
return value_a,value_b,value_c,value_d
这样你就可以摆脱if
/ elif
。
答案 3 :(得分:0)
您可以使用以下内容:
def relations(a=None, b=None, c=None, d=None):
if a is not None:
pass
elif b is not None:
a = b - 1
elif c is not None:
a = 2 * c
elif d is not None:
a = d ** 2
else:
raise TypeError('At least one argument needed')
# your calculations
然后你可以简单地使用这个功能,例如relations(c=10)
或relations(a=2)
。
所以你不需要vtype
参数。
第一个传递的参数用于计算a
。如果您使用多个参数调用该函数,则仅使用第一个函数,而忽略其他函数(例如relations(b=2, c=5)
将仅使用b
并忽略c
。