"else" 在 "if" 之前执行的语句 在 Python 中使用 `undo` 之后的语句
"else" statement executed before "if" statement after `undo` is used in Python
我创建了以下功能,允许用户将 Python 海龟的形状更改为图像 he/she 从文件对话框中选择当特定按钮被弹出时文件对话框按下:
def TurtleShape(iop = None):
# "iop" is supposed to be an image path
try:
manipulateimage.config(state = NORMAL)
flipButton.config(state = NORMAL)
mirrorButton.config(state = NORMAL)
originalButton.config(state = NORMAL)
resetturtle.config(state = NORMAL)
rotateButton.config(state = NORMAL)
global klob
# The following "if-else" statement uses the "iop" argument's value as the value for "klob" if `iop` is NOT `None`
if iop != None:
klob = iop
print("lmcv")
else:
klob = filedialog.askopenfilename()
print("klobby")
global im
im = Image.open(klob)
pictures.append(im)
edited.clear()
print(im)
im.save(klob + '.gif', "GIF")
register_shape(klob + '.gif')
shape(klob + '.gif')
update()
except:
pass
上面的函数也应该使用 iop
参数的值作为海龟的图像,如果它不是 None
。
现在,考虑一下这种情况;你画了一堆东西,将海龟设置为图像,就在你要标记图像时,你不小心按下了将海龟重置为正常形状的按钮(是的,那个按钮存在于我的程序)。 哦不!如果不经过所有步骤再次打开和编辑它,您将如何取回它?好吧,这就是我的 undoHandler 函数(如下所示)发挥作用的地方。它实际上只是撤消使用许多堆栈调用的最后一个函数,我将其创建为 deque
s。如果你精通 Python:
就很简单了
def undoHandler():
if len(function) > 0 and draw.drawing == True:
undoHandler.handling = True
if not hasattr(undoHandler, "counter"):
undoHandler.counter = 0
undoHandler.counter += 1
# clear the canvas
Clear()
# Pop a point object from function deque
function.pop()
penup()
goto(-200, 100)
pendown()
try:
# Execute everything up to point before last function called
for i in function:
# Set canvas and turtle to previous state
tsd = i.recieveshape()
shape(tsd)
mndf = i.recieveheading()
setheading(mndf)
hk = i.getletterheight()
global letter_height
letter_height = hk
rk = i.getletterwidth()
global letter_width
letter_width = rk
milk = i.getspacewidth()
global space_width
space_width = milk
hw = i.getwidth()
width(hw)
op = i.getcolor()
try:
color(op)
except:
for g in colors:
cp = g.getcolor2()
colormode(255)
color(cp)
# Get function wrapped in Point object and execute it
j = i.getfunction()
j()
# Following is the code block where the issue occurs. Basically, if the function being run is equal to `TurtleShape`, then do the following...
if j.__name__ == "TurtleShape":
# `hfl` is a deque that holds all of the `pictures` deque's contents as it is cleared when the turtle is set to its default state
pictures.extend(hfl)
lmcv = pictures.pop()
pictures.append(lmcv)
try:
# Resize image to previous size if user changes it. Otherwise, skip this.
bun = picwidth.pop()
picwidth.append(bun)
mun = picheight.pop()
picheight.append(mun)
clob = lmcv.resize((int(bun), int(mun)), Image.ANTIALIAS)
except:
clob = lmcv
clob.save(klob + str(undoHandler.counter) + ".gif")
# Use the `clob.save` output from above as source image in `TurtleShape` function (this is where issue occurs)
TurtleShape(klob + str(undoHandler.counter) + ".gif")
print("Undone!")
else:
pass
except:
pass
基本上这里发生的是它从队列中获取函数(包装在 Point
对象中),主要函数在调用时通过该队列。然后函数被附加到 function
双端队列,之后,当用户调用 undoHandler
时,屏幕被清除,最新的值从 function
双端队列中弹出,以便所有其他动作 除了 最后一个将再次执行。我面临的这个问题专门发生在 if j.__name__ == "TurtleShape":
代码块中。基本上,出于某种原因,当用户选择撤消将海龟重置为其原始形状时,它会按原样工作直到 TurtleShape
函数由 undoHandler 执行. 出于某种原因,当 undoHandler 执行 TurtleShape
函数时,即使我为 TurtleShape
函数的 iop
属性提供了有效参数(如您在if j.__name__ == "TurtleShape":
代码块),else
语句首先被执行 (即出现文件对话框而不是从 if
语句继续)。仅当用户在该对话框中单击 cancel
时,海龟才会设置为上一张图像。
我的代码有什么问题导致了这种情况发生,我该如何阻止这种情况发生?我试过了例如,将输出保存在 undoHandler
函数中的函数中的 klob
属性更改为 "SaveImage"
,但仍然没有成功。我还尝试在 TurtleShape
中添加一条 if-elif
语句,当它应该在 iop
或文件对话框之间进行选择作为 klob
的值时,但问题仍然存在发生。显然,它会执行 elif
语句 ,即使它不一定为真。 因此,非常感谢任何帮助解决此问题! :)
发生在这里:
j = i.getfunction()
j()
如果您刚刚获得的函数是 TurtleShape()
函数,那么您将使用其默认参数(即 iop = None
)调用它一次。然后你进入你的大 if j.__name__ == "TurtleShape":
语句并在 if
块中再次调用它。
将 j()
调用移到 if j.__name__ == "TurtleShape":
大语句的 else:
块中,您的问题就会消失。
这个简短的解释是否足以让您理解为什么会出现这个问题?或者你需要我解释一下 in-depth 调用 j()
是如何使用参数 iop = None
调用 TurtleShape
?
我创建了以下功能,允许用户将 Python 海龟的形状更改为图像 he/she 从文件对话框中选择当特定按钮被弹出时文件对话框按下:
def TurtleShape(iop = None):
# "iop" is supposed to be an image path
try:
manipulateimage.config(state = NORMAL)
flipButton.config(state = NORMAL)
mirrorButton.config(state = NORMAL)
originalButton.config(state = NORMAL)
resetturtle.config(state = NORMAL)
rotateButton.config(state = NORMAL)
global klob
# The following "if-else" statement uses the "iop" argument's value as the value for "klob" if `iop` is NOT `None`
if iop != None:
klob = iop
print("lmcv")
else:
klob = filedialog.askopenfilename()
print("klobby")
global im
im = Image.open(klob)
pictures.append(im)
edited.clear()
print(im)
im.save(klob + '.gif', "GIF")
register_shape(klob + '.gif')
shape(klob + '.gif')
update()
except:
pass
上面的函数也应该使用 iop
参数的值作为海龟的图像,如果它不是 None
。
现在,考虑一下这种情况;你画了一堆东西,将海龟设置为图像,就在你要标记图像时,你不小心按下了将海龟重置为正常形状的按钮(是的,那个按钮存在于我的程序)。 哦不!如果不经过所有步骤再次打开和编辑它,您将如何取回它?好吧,这就是我的 undoHandler 函数(如下所示)发挥作用的地方。它实际上只是撤消使用许多堆栈调用的最后一个函数,我将其创建为 deque
s。如果你精通 Python:
def undoHandler():
if len(function) > 0 and draw.drawing == True:
undoHandler.handling = True
if not hasattr(undoHandler, "counter"):
undoHandler.counter = 0
undoHandler.counter += 1
# clear the canvas
Clear()
# Pop a point object from function deque
function.pop()
penup()
goto(-200, 100)
pendown()
try:
# Execute everything up to point before last function called
for i in function:
# Set canvas and turtle to previous state
tsd = i.recieveshape()
shape(tsd)
mndf = i.recieveheading()
setheading(mndf)
hk = i.getletterheight()
global letter_height
letter_height = hk
rk = i.getletterwidth()
global letter_width
letter_width = rk
milk = i.getspacewidth()
global space_width
space_width = milk
hw = i.getwidth()
width(hw)
op = i.getcolor()
try:
color(op)
except:
for g in colors:
cp = g.getcolor2()
colormode(255)
color(cp)
# Get function wrapped in Point object and execute it
j = i.getfunction()
j()
# Following is the code block where the issue occurs. Basically, if the function being run is equal to `TurtleShape`, then do the following...
if j.__name__ == "TurtleShape":
# `hfl` is a deque that holds all of the `pictures` deque's contents as it is cleared when the turtle is set to its default state
pictures.extend(hfl)
lmcv = pictures.pop()
pictures.append(lmcv)
try:
# Resize image to previous size if user changes it. Otherwise, skip this.
bun = picwidth.pop()
picwidth.append(bun)
mun = picheight.pop()
picheight.append(mun)
clob = lmcv.resize((int(bun), int(mun)), Image.ANTIALIAS)
except:
clob = lmcv
clob.save(klob + str(undoHandler.counter) + ".gif")
# Use the `clob.save` output from above as source image in `TurtleShape` function (this is where issue occurs)
TurtleShape(klob + str(undoHandler.counter) + ".gif")
print("Undone!")
else:
pass
except:
pass
基本上这里发生的是它从队列中获取函数(包装在 Point
对象中),主要函数在调用时通过该队列。然后函数被附加到 function
双端队列,之后,当用户调用 undoHandler
时,屏幕被清除,最新的值从 function
双端队列中弹出,以便所有其他动作 除了 最后一个将再次执行。我面临的这个问题专门发生在 if j.__name__ == "TurtleShape":
代码块中。基本上,出于某种原因,当用户选择撤消将海龟重置为其原始形状时,它会按原样工作直到 TurtleShape
函数由 undoHandler 执行. 出于某种原因,当 undoHandler 执行 TurtleShape
函数时,即使我为 TurtleShape
函数的 iop
属性提供了有效参数(如您在if j.__name__ == "TurtleShape":
代码块),else
语句首先被执行 (即出现文件对话框而不是从 if
语句继续)。仅当用户在该对话框中单击 cancel
时,海龟才会设置为上一张图像。
我的代码有什么问题导致了这种情况发生,我该如何阻止这种情况发生?我试过了例如,将输出保存在 undoHandler
函数中的函数中的 klob
属性更改为 "SaveImage"
,但仍然没有成功。我还尝试在 TurtleShape
中添加一条 if-elif
语句,当它应该在 iop
或文件对话框之间进行选择作为 klob
的值时,但问题仍然存在发生。显然,它会执行 elif
语句 ,即使它不一定为真。 因此,非常感谢任何帮助解决此问题! :)
发生在这里:
j = i.getfunction()
j()
如果您刚刚获得的函数是 TurtleShape()
函数,那么您将使用其默认参数(即 iop = None
)调用它一次。然后你进入你的大 if j.__name__ == "TurtleShape":
语句并在 if
块中再次调用它。
将 j()
调用移到 if j.__name__ == "TurtleShape":
大语句的 else:
块中,您的问题就会消失。
这个简短的解释是否足以让您理解为什么会出现这个问题?或者你需要我解释一下 in-depth 调用 j()
是如何使用参数 iop = None
调用 TurtleShape
?