嘗試一些想法......
它看起來像你最好要具有副作用的表達。如果Python允許這樣做:
if m = re.match('foo (\w+) bar (\d+)', line):
# do stuff with m.group(1) and m.group(2)
elif m = re.match('baz whoo_(\d+)', line):
# do stuff with m.group(1)
elif ...
......那麼你會清楚地乾淨地表達你的意圖。但事實並非如此。如果副作用在嵌套函數允許,你可以:
m = None
def assign_m(x):
m = x
return x
if assign_m(re.match('foo (\w+) bar (\d+)', line)):
# do stuff with m.group(1) and m.group(2)
elif assign_m(re.match('baz whoo_(\d+)', line)):
# do stuff with m.group(1)
elif ...
現在,不僅是越來越難看,但它仍然不是有效的Python代碼 - 嵌套函數「assign_m」是不允許修改變量m
在外部範圍內。我能想出的最好的是真的難看,用它允許副作用嵌套類:
# per Brian's suggestion, a wrapper that is stateful
class m_(object):
def match(self, *args):
self.inner_ = re.match(*args)
return self.inner_
def group(self, *args):
return self.inner_.group(*args)
m = m_()
# now 'm' is a stateful regex
if m.match('foo (\w+) bar (\d+)', line):
# do stuff with m.group(1) and m.group(2)
elif m.match('baz whoo_(\d+)', line):
# do stuff with m.group(1)
elif ...
但是,這顯然矯枉過正。
您migth考慮使用一個內部函數,以允許本地範圍退出,它允許你刪除else
嵌套:
def find_the_right_match():
# now 'm' is a stateful regex
m = re.match('foo (\w+) bar (\d+)', line)
if m:
# do stuff with m.group(1) and m.group(2)
return # <== exit nested function only
m = re.match('baz whoo_(\d+)', line)
if m:
# do stuff with m.group(1)
return
find_the_right_match()
這允許您弄平嵌套=(2 * N-1)至嵌套= 1 ,但是你可能剛剛提出了副作用問題,嵌套函數很可能會混淆大多數Python程序員。
最後,有處理這個免費的副作用-方式:
def cond_with(*phrases):
"""for each 2-tuple, invokes first item. the first pair where
the first item returns logical true, result is passed to second
function in pair. Like an if-elif-elif.. chain"""
for (cond_lambda, then_lambda) in phrases:
c = cond_lambda()
if c:
return then_lambda(c)
return None
cond_with(
((lambda: re.match('foo (\w+) bar (\d+)', line)),
(lambda m:
... # do stuff with m.group(1) and m.group(2)
)),
((lambda: re.match('baz whoo_(\d+)', line)),
(lambda m:
... # do stuff with m.group(1)
)),
...)
而且現在的代碼勉強甚至看起來像Python,更不用說理解的Python程序員(是Lisp的?) 。
我認爲這個故事的寓意是Python並沒有爲這種成語優化。你確實需要做一些細節處理,並且在其他條件下使用較大的嵌套因子。
我希望模塊也有一個保持狀態的形式。但是我不認爲創建自己的保持狀態的對象是件難事。看起來像一個乾淨,本地化和明確的解決方案給我。 – 2009-01-16 15:35:39