[英]Python 3. Confusing issue with 'exec' function
我一直在使用 tkinter 為 gui 開發我的蛇游戲。 問題出在其中一項功能上。
該函數應該分別使用 Canvas().create_rectangle 和 Canvas().create_oval 繪制身體片段和水果。 因此,我沒有為每種情況編寫單獨的代碼,而是決定編寫一次,然后使用“shape”參數對其進行修改,即“矩形”或“橢圓形”。 函數還必須為自己的目的返回繪制元素的 id。 最初那部分代碼如下所示:
exec(
"""
segment_id = self.grid.create_{}(coords,
[coord + self.pxSize for coord in coords],
fill=color, tag=tag, width=0)
""".format(shape))
return segment_id
而不是得到一個常見的NameError: name 'segment_id' is not defined
,我得到了NameError: name 'self' is not defined
。
谷歌搜索后,我只發現了這個:
ldict = {}
exec('var = something', globals(), ldict)
var = ldict['var']
這解決了NameError: name 'segment_id' is not defined
,但沒有解決另一個。 所以使用科學的 poke 方法,我通過將 locals() 傳遞給它的“globals”參數來修復它。 它有效,現在我更困惑了。
這是代碼:
class Game(Tk):
def __init__(self):
...
# ...
def drawSegment(self, position, color, tag, shape, id_=None):
coords = self.field.from_1D_to_2D(position)
coords = [i * self.pxSize for i in coords]
# id > 1, otherwise deletes background
if id_ and id_ > 1:
self.grid.delete(id_)
# ???
ldict = {}
exec(
"""
segment_id = self.grid.create_{}(coords,
[coord + self.pxSize for coord in coords],
fill=color, tag=tag, width=0)
""".format(shape), locals(), ldict)
segment_id = ldict['segment_id']
return segment_id
# ...
我需要的是關於它為什么起作用以及發生了什么的答案。
像這樣使用 exec 是不必要的,而且正如您所遇到的那樣,非常令人困惑; 所以我有兩個不同的答案給你。
這是怎么回事?
當您將globals=globals(), locals=ldict
給exec
,它將在只能看到globals
和ldict
的范圍內執行代碼; 所以特別是,它不會看到任何局部於drawSegment
方法局部范圍的變量。 由於self
僅在此本地范圍內定義,為了從exec
調用內部引用self
,您需要傳入locals()
,而不僅僅是globals()
。
你應該怎么做?
而不是動態執行基於的值的代碼全塊shape
,可以只動態查找所需CREATE_ *基於方法shape
:
creator = getattr(self.grid, 'create_{}'.format(shape))
segment_id = creator(coords, [coord + self.pxSize for coord in coords],
fill=color, tag=tag, width=0)
如果您知道形狀只有兩種可能性,那么根據個人品味,您可能會更加明顯:
creator = self.grid.create_oval if shape == 'oval' else self.grid.create_rectangle
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.