我的代码如下:
if(func_cliche_start(line)):
a=func_cliche_start(line)
#... do stuff with 'a' and line here
elif(func_test_start(line)):
a=func_test_start(line)
#... do stuff with a and line here
elif(func_macro_start(line)):
a=func_macro_start(line)
#... do stuff with a and line here
...
每个func_blah_start函数都返回None或字符串(基于输入行)。我不喜欢对func_blah_start的冗余调用,因为它似乎是浪费(func_blah_start是“纯粹的”,所以我们可以假设没有副作用)。是否有更好的习惯用于此类事情,或者有更好的方法吗?
也许我错了,(我的C生锈了),但我认为你可以用C做一些事情:
int a;
if(a=myfunc(input)){ /*do something with a and input here*/ }
是否有python等价物?
答案 0 :(得分:4)
为什么不在if语句之前将函数func_cliche_start赋值给变量a?
a = func_cliche_start(line)
if a:
pass # do stuff with 'a' and line here
如果func_cliche_start(line)返回None,则if语句将失败。
答案 1 :(得分:3)
您可以创建一个包装函数来使其工作。
def assign(value, lst):
lst[0] = value
return value
a = [None]
if assign(func_cliche_start(line), a):
#... do stuff with 'a[0]' and line here
elif assign(func_test_start(line), a):
#...
答案 2 :(得分:2)
你可以通过你的处理函数循环,这将更容易和更少的行:),如果你想在每种情况下做一些不同的事情,将它包装在一个函数中并调用它,例如。
for func, proc in [(func_cliche_start, cliche_proc), (func_test_start, test_proc), (func_macro_start, macro_proc)]:
a = func(line)
if a:
proc(a, line)
break;
答案 3 :(得分:0)
我认为你应该将这些代码块放在函数中。这样你就可以使用dispatcher
式的方法。如果需要修改很多本地状态,请使用类和方法。 (如果没有,只需使用函数;但我会在这里假设类的情况。)所以这样的事情:
from itertools import dropwhile
class LineHandler(object):
def __init__(self, state):
self.state = state
def handle_cliche_start(self, line):
# modify state
def handle_test_start(self, line):
# modify state
def handle_macro_start(self, line):
# modify state
line_handler = LineHandler(initial_state)
handlers = [line_handler.handle_cliche_start,
line_handler.handle_test_start,
line_handler.handle_macro_start]
tests = [func_cliche_start,
func_test_start,
func_macro_start]
handlers_tests = zip(handlers, tests)
for line in lines:
handler_iter = ((h, t(line)) for h, t in handlers_tests)
handler_filter = ((h, l) for h, l in handler_iter if l is not None)
handler, line = next(handler_filter, (None, None))
if handler:
handler(line)
这比原始代码复杂一点,但我认为它以更加可扩展的方式划分事物。它确实需要你维护单独的并行函数列表,但是回报是你可以添加任意多个函数,而不必编写长if
语句 - 或者调用你的函数两次!可能还有更复杂的组织方式 - 这实际上只是一个粗略的例子,说明你可以做些什么。例如,您可能能够创建一个满载(priority, test_func, handler_func)
元组的已排序容器并对其进行迭代。
无论如何,我认为您应该考虑重构这个if
/ elif
条款的长列表。
答案 4 :(得分:0)
您可以获取一系列函数,使其成为生成器并返回第一个Truey:
functions = [func_cliche_start, func_test_start, func_macro_start]
functions_gen = (f(line) for f in functions)
a = next((x for x in functions_gen if x), None)
看起来仍然有点奇怪,但重复次数要少得多。