3

我有一个函数可以打开一个文本文件,解析一堆数据并在一个数组中返回数值结果。现在,我还希望此函数即时执行一些可选计算,并在需要时返回这些值。

对于单个标志,这是相当干净的,例如:

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

有没有更清洁的方法来处理这种情况?

4

5 回答 5

1

我通常会做类似的事情:

ret = (xyz,)
if calc_a:
    ret += (abc,)
if calc_b:
    ret += (def,)

return ret[0] if len(ret) == 1 else ret

如果您使用大量变量执行此操作,请考虑使用 anamedtuple或 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)
于 2013-10-14T02:54:10.930 回答
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')
于 2013-10-14T03:14:41.757 回答
0

也许类似于论点拆包的东西?

http://hangar.runway7.net/python/packing-unpacking-arguments

于 2013-10-14T02:54:51.850 回答
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)
于 2013-10-14T02:59:55.847 回答
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

(老实说,我可能会这样做。我可能会重新表述问题,以便我的函数返回有用的值。但我不知道你的约束。)

于 2013-10-14T03:08:18.980 回答