Python 基于输入标志返回不同变量的优雅方式

Python 基于输入标志返回不同变量的优雅方式,python,return,Python,Return,我有一个函数,它打开一个文本文件,解析一组数据,并返回数组中的数值结果。现在,我还希望这个函数能够动态地执行一些可选的计算,并在需要时返回这些值 对于单个标志,这是相当干净的,例如: 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'

我有一个函数,它打开一个文本文件,解析一组数据,并返回数组中的数值结果。现在,我还希望这个函数能够动态地执行一些可选的计算,并在需要时返回这些值

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

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

有没有更干净的方法来处理这种情况?

我通常会这样做:

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

return ret[0] if len(ret) == 1 else ret
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)
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

如果使用很多变量,请考虑使用A或DICT来返回子集以便于使用。对于namedtuple,这看起来像:

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

return ret[0] if len(ret) == 1 else ret
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)
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

也许是一些类似于论点的东西


现在,对于一些完全过度的事情

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)

我可能会使用带有可链接方法的类

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
然后,您可以执行以下操作:

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

return ret[0] if len(ret) == 1 else ret
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)
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

(说实话,我可能不会这么做。我可能会重新设计问题,以便我的函数返回有用的值。但我不知道您的限制。)

拥有一个返回不同数量的类似内容的函数本身就有点尴尬。相反,为什么不总是返回一些数据结构,其中包含每个信息段的插槽,如果不计算这些信息,其中一些可能没有插槽。(例如,返回一个列表,其中某些元素可能不存在)。拥有一个基于参数选择要运行的计算的函数非常类似于拥有一个带有方法的类。除此之外:
def
是Python关键字,因此不能用作名称。这可能有助于我理解为什么需要将各种结果存储在这样任意的变量名中。有没有什么特别的原因让你不能只返回一个内容列表…我看不出这在这种情况下有什么帮助…?让我们不要在压力下崩溃。这让我想到我见过的大多数LINQ:(