想象一下,我有一个带有一些功能的Python模块:
def sumvars(x, y, z):
s = x
s += y
s += z
return s
Run Code Online (Sandbox Code Playgroud)
但有时候我想得到一些中间计算的结果(例如,我可以有一个反转矩阵的函数,并且想知道已经计算为中间步骤的行列式).显然,如果它们已经在该函数中完成,我不想再次重做那些计算.
我的第一个想法是返回一个字典:
def sumvars(x, y, z):
d = {}
s = x
d['first_step'] = s
s += y
d['second_step'] = s
s += z
d['final'] = s
return d
Run Code Online (Sandbox Code Playgroud)
但我不记得numpy或scipy中返回dicts的任何函数,所以看起来这可能不是一个好主意.(为什么?)通常情况下,我总是要输入sumvars(x,y,z)['final']默认的返回值...
我看到的另一个选项是创建全局变量,但在我的模块中有一堆它们似乎是错误的,我需要记住它们的名字,另外没有附加到函数本身看起来像一个糟糕的设计选择.
对于这种情况,适当的功能设计是什么?
将常用计算放入其自己的函数中,如Jayanth Koushik建议的那样,如果该计算可以恰当地命名.如果你想从一个单一的函数返回多个值(中间结果和最终结果),那么字典可能取决于什么是你的目标,但在Python它更自然只返回一个元组,如果你的函数是矫枉过正要返回的许多值:
def myfunc():
intermediate = 5
result = 6
return intermediate, result
# using the function:
intermediate, result = myfunc()
Run Code Online (Sandbox Code Playgroud)
不确定函数属性是否是一个好主意:
In [569]: def sumvars(x, y, z):
...: s = x
...: sumvars.first_step = s
...: s += y
...: sumvars.second_step = s
...: s += z
...: return s
In [570]: res=sumvars(1,2,3)
...: print res, sumvars.first_step, sumvars.second_step
...:
6 1 3
Run Code Online (Sandbox Code Playgroud)
注意:正如@BrenBarn所提到的,这个想法就像全局变量一样,当您要重用它们时,先前存储的“中间结果”将无法存储。
通常,当您有两种不同的方式返回数据时,请继续执行两种不同的功能.毕竟,"扁平比嵌套更好".只要一个人打电话给另一个,这样你就不要重复自己了.
例如,在标准库中,urllib.parsehas parse_qs(返回a dict)和parse_qsl(返回a list). parse_qs然后调用另一个:
def parse_qs(...):
parsed_result = {}
pairs = parse_qsl(qs, keep_blank_values, strict_parsing,
encoding=encoding, errors=errors)
for name, value in pairs:
if name in parsed_result:
parsed_result[name].append(value)
else:
parsed_result[name] = [value]
return parsed_result
Run Code Online (Sandbox Code Playgroud)
非常直截了当.所以在你的例子中似乎很好
def sumvars(x, y, z):
return sumvars_with_intermediates(x, y, z).final
def sumvars_with_intermediates(x, y, z):
...
return my_namedtuple(final, first_step, second_step)
Run Code Online (Sandbox Code Playgroud)
(我赞成从我的API 返回namedtuples而不是dicts,它更漂亮)
另一个明显的例子是re:re.findall它是自己的函数,而不是一些配置标志search.
现在,标准库是许多作者制作的庞大的东西,所以你会发现每个例子的反例.你会经常看到上面的模式,而不是一个接受一些配置标志的综合函数,我觉得它更具可读性.
| 归档时间: |
|
| 查看次数: |
1522 次 |
| 最近记录: |