我有一个打开文本文件的函数,解析一堆数据并在数组中返回数值结果。现在我还想让这个函数动态地做一些可选的计算,并在需要时返回这些值。
对于单个标志,这是相当干净的,例如:
def read_data(file_name, calc_a=False):
# do normal parsing and store data in 'xyz'
if calc_a:
# calc some other stuff and store in 'a'
return xyz, a
else:
return xyz
现在,如果我想拥有多个可选标志,很快就会变得混乱,例如:
def read_data(file_name, calc_a=False, calc_b=False):
# do normal parsing and store data in 'xyz'
if calc_a:
# calc some other stuff and store in 'a'
if calc_b:
# calc some other stuff and store in 'b'
if calc_a and calc_b:
return xyz, a, b
elif calc_a:
return xyz, a
elif calc_b:
return xyz, b
else:
return xyz
有没有更清洁的方法来处理这种情况?
答案 0 :(得分:1)
我通常会这样做:
ret = (xyz,)
if calc_a:
ret += (abc,)
if calc_b:
ret += (def,)
return ret[0] if len(ret) == 1 else ret
如果您使用大量变量进行此操作,请考虑使用namedtuple
或dict返回子集以方便使用。对于namedtuple,它看起来像:
fields = ['regular_ans']
ret = [xyz]
if calc_a:
fields.append('a')
ret.append(abc)
if calc_b:
fields.append('b')
ret.append(def)
if len(ret) == 1:
return ret[0]
return namedtuple('ResultType', fields)(*ret)
答案 1 :(得分:1)
def read_data(file_name, *extras):
# Read the data from file_name, organizing in a dict,
# using the key names that your caller will pass into the function.
# In this example, we have the main data that will always be
# returned, plus optional data stored under keys a, b, c, d.
data = dict(_main = 'MAIN', a = 'AA', b = 'BB', c = 'CC', d = 'DD')
# Return a tuple, list, or even dict of that data.
ks = sorted(data.keys())
return tuple(data[k] for k in ks if k in extras or k == '_main')
# Caller requests the optional data they want.
# This example shows the caller passing a list of optional data keys.
# You could also have them pass keyword args instead.
wanted = 'a b d'.split()
print read_data('data_file', *wanted) # ('MAIN', 'AA', 'BB', 'DD')
答案 2 :(得分:0)
可能还有什么东西沿着论证解包?
http://hangar.runway7.net/python/packing-unpacking-arguments
答案 3 :(得分:0)
现在对于一些完全过度的事情......
import operator
pMap = {
(False, False): ('foo',),
(False, True): ('foo', 'bar'),
(True, False): ('foo', 'bar'),
(True, True): ('foo', 'bar', 'baz')
}
def func(var, pred1=False, pred2=False):
# calculations go here
return operator.itemgetter(*pMap[bool(pred1), bool(pred2)])(dict(foo=1, bar=2, baz=3))
print func(None)
print func(None, pred2=True)
print func(None, True, True)
答案 4 :(得分:0)
我可能会使用带有可链接方法的类。
class DataReader(object):
abc = None
deef = None
def __init__(self, file_name):
self.xyz = self.normal_parsing(file_name)
def calc_a(self):
self.abc = some_calculation(self.xyz)
return self
def calc_b(self):
self.deef = othr_calculation(self.xyz)
return self
然后你可以做类似的事情:
dr = DataReader("watfile").calc_a().calc_b()
# Now you have access to dr.xyz, dr.abc and dr.deef.
# If you don't run all the methods, some of those would be None
(说实话,我可能不会这样做。我可能会重新解决问题,以便我的函数返回有用的值。但我不知道你的约束。)