问题描述
您好,
我正在尝试使用Python学习/理解OOP原则。代码为
PyCon TX 2006
Python places great store on backwards-compatibility. Consequently I''d
suggest you try the code out, and report any problems you find back on
this list. I''d give you odds it will work.
regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/
Python没有goto。
如果你想到可能的话通过函数执行路径,你可以将
表示为有限状态机:FSM只是一个图形,并且函数中的
,你通过对待得到一个FSM每个语句作为一个节点,并且
语句可以遵循该语句(在执行顺序中)具有
a(定向)边缘给他们(让'忽略异常为此时此刻)。所以:
a = b
如果a == 3:
z = 0
else :
z = 1
打印''垃圾邮件''
我们得到:
(a = b) - > (如果a == 3) - > (z = 0)
| |
(z = 1) - > (打印''垃圾邮件)
现在,当我们想直接模拟函数中的FSM时(而不是某些较慢的表驱动方案),我们需要使用语言提供的构造
。但简单的''if''陈述并没有削减它。我们结束了
与:
而州!=''最终'':
如果州== 1:
#do state 1 stuff
state = 3
elif state == 2:
#if cond:
state == 1
else:
state == 99
elif
...
否则:
#未知状态
这种方法的问题在于,平均来说,你是''将对状态变量进行n / 2
比较。你想要的是直接从状态1直接跳到状态3到状态3,而不必去任何其他地方。你想要一个转到。
另一种无人转向的方法是使用函数。每个函数都是一个状态,
为下一个状态函数设置一个全局函数变量:
def f_state_1():
global func
#do state 1
func = f_state_3
def f_state_2():
global func
#do state_2 stuff
if cond:
func = f_state_1
else:
func = f_state_99
#etc。
func = f_state_1 #start_state
而func!=无:
func()
我们已经消除了无数的比较,可以说,更多是
pythonic。但是现在你在每个状态上都有一个函数调用开销
转换,并且状态之间共享的任何信息都必须在
封闭范围内。
我们想要一个goto。
不幸的是,这是我能想到的唯一问题,其中getos
是有用的。并且由于其他地方得到很好解释的原因,得到的并不好。
我已经用一种非常有效但非常简单的方式解决了这个问题。
首先,您以第一种方式编写(或生成)代码
以上。在一个大函数中有很多低效的if语句(比如,
''fsm'')。然后,你编写另一个函数(比如''gotoize''),它将fsm
作为参数,并且*将fsm代码对象的字节代码*更改为
添加JUMP_ABSOLUTE字节码(即gotos),其中''state''变量获得
重新分配。
fsm然后可以用gotoize进行装饰,你的速度非常快(对于
python)FSM。实际上,你正在做一些(相当简单的)字节码
优化。
如果你感兴趣我可以挖出代码(除了它'现在非常凌乱
。我很惭愧地把它显示在当前状态:-)
哎呀。我只是重读了你的帖子并且你声称(或者是那个辩护?)
newbie状态。对不起,如果这是你的头脑。无论如何希望它有所帮助。
欢呼,
Carl。
Python has no goto.
If you think about the possible execution paths through a function, you
can represent that as a finite state machine: A FSM is just a graph, and
in a function, you get a FSM by treating each statement as a node, and
statements that can follow that statement (in the execution order) have
a (directed) edge to them (let''s ignore exceptions for the moment). So for:
a=b
if a == 3:
z = 0
else:
z = 1
print ''spam''
we get:
(a=b) -> (if a == 3) -> (z = 0)
| |
(z = 1) -> (print ''spam)
Now, when we want to emulate a FSM in a function directly (rather than
some slower table-driven scheme), we need to use the constructs provided
by the language. But simple ''if'' statements just don''t cut it. We end up
with:
while state != ''final'':
if state == 1:
# do state 1 stuff here
state = 3
elif state == 2:
# if cond:
state == 1
else:
state == 99
elif
...
else:
# unknown state
Problem with this approach is that, on average, you''ll have n/2
comparisons of the state variable. What you want is to jump directly
from state 1 to state 3 without having to go anywhere else. You want a goto.
Another goto-less way is with functions. Each function is a state, which
sets a global function variable to the next state-function:
def f_state_1():
global func
# do state 1
func = f_state_3
def f_state_2():
global func
# do state_2 stuff
if cond:
func = f_state_1
else:
func = f_state_99
#etc.
func = f_state_1 # start_state
while func != None:
func()
We''ve eliminated the numerous comparisons, and it is, arguably, more
pythonic. But now you have a function-call overhead on each state
transition, and any information shared between states has to be in an
enclosing scope.
We want a goto.
Unfortunately, this is about the only problem I can think of where gotos
are useful. And for reasons well explained elsewhere, gotos are Not Good.
I''ve solved this in a very efficient, but rather unpythonic way.
First, you write (or generate) the code in the first way indicated
above. Lots of inefficient ''if'' statements in one big function (say,
''fsm''). Then, you write another function (say ''gotoize'') which takes fsm
as an argument, and *changes the byte code* of the fsm code object to
add JUMP_ABSOLUTE bytecodes (i.e. gotos) where the ''state'' variable gets
reassigned.
fsm can then be decorated with gotoize, and you have a very fast (for
python) FSM. You are, essentially, doing some (fairly simple) byte-code
optimisation.
I can dig out the code if you are interested (except it''s pretty untidy
at the moment. I''d be ashamed to show it in it''s current state :-)
Ooops. I just reread your post and you claim (or is that plead?)
"newbie" status. Sorry if this is over your head. Hope it helps anyway.
Cheers,
Carl.
不,我们不是。
问候,
Dan
-
Dan Sommers
< http:/ /www.tombstonezero.net/dan/>
No, we don''t.
Regards,
Dan
--
Dan Sommers
<http://www.tombstonezero.net/dan/>
这篇关于1998年编写的Python代码,如何改进/改变呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!