我正在构建一个函数来构造具有设置属性的对象(类似于namedtuple);但是,输出长度必须可变。
我想构建一个函数,该函数允许用户通过函数调用附加其他属性。重要的是,我想找到一种方法来“短路”参数,并且不确定Python是否足够强大来做到这一点。
以这个简单的例子来解释:
def foo():
print("foo")
return False
def bar():
print("bar")
return True
if foo() and bar():
pass
Foo的函数调用返回False,并且Bar短路。输出控制台将仅打印foo,并且不会执行 bar 。
是否存在通过检查或反映函数调用来模仿此行为的方法。这是我的实现示例,如下所示:
from inspect import stack
cache = {}
def fooFormat(**kwargs):
caller = stack()[1][3]
if caller not in cache:
class fooOut(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def optional(self, opt, **kwargs):
if (opt):
self.__dict__.update(kwargs)
return self
def __str__(self):
return caller + str(self.__dict__)
cache[caller] = iadsOut
return cache[caller](**kwargs)
def stdev(nums, avg = None):
print("\tStdev call")
if avg is None:
avg = sum(nums) / len(nums)
residuals = sum((i - avg)**2 for i in nums)
return residuals**.5
def stats(nums, verbose=False):
if verbose:
print("Stats call with verbose")
else:
print("Stats call without verbose")
total = sum(nums)
N = len(nums)
avg = total / N
return fooFormat(
avg = avg,
lowerB = min(nums),
upperB = max(nums)).optional(verbose,
stdev = stdev(nums, avg))
在函数“ stats”中,返回fooFormat当然应该产生avg,lowerB和upperB;此外,如果将verbose设置为True,它应该产生std。此外,如果将verbose设置为False,则不应调用函数'stdev'。
stats([1,2,3,4], False)
stats([1,2,3,4], True)
当然,解决此问题的方法是:
if verbose:
return fooFormat(
avg = avg,
lowerB = min(nums),
upperB = max(nums),
stdev = stdev(nums, avg))
else:
return fooFormat(
avg = avg,
lowerB = min(nums),
upperB = max(nums))
但是,我希望在那里实现这种行为而无需分支。
答案 0 :(得分:1)
这并不能完全解决快捷方式问题,但这是一种更有效的编写方式:
out_dic = { # these items will always be calculated
'avg': avg,
'lowerB':max(nums),
'upperB':min(nums)
}
if verbose: # this is calculated only if verbose
out_dic['stdev'] = stdev(nums,avg)
return fooFormat(**out_dic)
换句话说,您可以将字典扩展到kwargs
,然后动态添加到字典中。