简体   繁体   English

从字典值中检索函数

[英]Retrieving functions from dictionary values

all! 所有! As a personal project of mine, I'm attempting to convert a dice roll animation in tkinkter from using only if statements to dictionary values instead. 作为我的个人项目,我尝试将tkinkter中的骰子滚动动画从仅使用if语句转换为字典值。 I'm essentially doing this: 我基本上是这样做的:

def draw_dice(*args):
    w,h = 23, 23
    x,y,r = 2,2,5
    c = tk.Canvas(root,width=w,height=h,bg='white')

    dots = {
        'dot0':None,
        'dot1':c.create_oval(x, y, x + r, y + r, fill='black'),
        'dot2':c.create_oval(x + 16, y, (x + 16) + r, y + r, fill='black'),
        'dot3':c.create_oval(x, y + 8, x + r, (y + 8) + r, fill='black'),
        'dot4':c.create_oval(x + 8, (y + 8), (x + 8) + r, (y + 8) + r, fill='black'),
        'dot5':c.create_oval(x + 16, (y + 8), (x + 16) + r, (y + 8) + r, fill='black'),
        'dot6':c.create_oval(x, y + 16, x + r, (y + 16) + r, fill='black'),
        'dot9':c.create_oval(x + 16, y + 18, (x + 16) + r, (y + 16) + r, fill='black')
    }

    for arg in args:
        dots.get(arg)

    return c

The code runs, but the output is not as expected. 该代码运行,但输出与预期的不同。 For the *args passed into the function, select values can be: 对于传递给函数的* args,选择值可以是:

'dot0', 'dot1'..., 'dot9' or just simply 'dot1'. 'dot0','dot1'...,'dot9'或仅是'dot1'。

Within another function of mine, I append the returned c (canvas) to a list that will shuffle through the various created dice faces to animate a rolling dice. 在我的另一个函数中,我将返回的c(画布)附加到列表中,该列表将通过创建的各种骰子面随机播放以为滚动骰子设置动画。

But, that's not the problem. 但是,这不是问题。 The problem is coming from this function. 问题来自此功能。 After running the debugger, I've discovered that the values for each key are like this: 运行调试器后,我发现每个键的值如下:

'dot0':None, 'dot1':1, 'dot2': 2, etc. 'dot0':无,'dot1':1,'dot2':2,等等。

Something odd is going on, but I'm suspicious that I may be using this data structure wrong. 发生了一些奇怪的事情,但是我怀疑自己可能使用了错误的数据结构。 Any help would be greatly appreciated! 任何帮助将不胜感激!

As it is, the dictionary does not have functions, it has the output of functions that have already been invoked. 实际上,字典没有功能,它具有已被调用的功能的输出。

At the time the interpreter sees the line 当时口译员看到了

 'dot1':c.create_oval(x, y, x + r, y + r, fill='black')

it actually runs the create_oval method, which returns an auto-incremented integer id for the oval. 它实际上运行create_oval方法,该方法为椭圆返回一个自动递增的整数id。 So, after that 'dot1': 1 因此,在'dot1': 1

if you want it to be a function you could do something like 如果您希望它成为一种功能,则可以执行以下操作

 'dot1': lambda x, y, r: c.create_oval(x, y, x + r, y + r, fill='black')

The same of all dotX keys. 所有dotX键均相同。 Then, you can call it in your loop by 然后,您可以在循环中通过以下方式调用它

 for arg in args:
     dots.get(arg)(x, y, r)

You have defined eg dot1 as: 您已将例如dot1定义为:

'dot1': c.create_oval(x, y, x + r, y + r, fill='black')

This is evaluated when your dictionary is created. 创建字典时会对此进行评估 The c.create_oval() function does not return anything, so it returns None . c.create_oval()函数不返回任何内容,因此它返回None This value is stored in the dictionary. 此值存储在字典中。

Presumably you want to defer execution of these calls until you actually call draw_dice() . 大概您想推迟执行这些调用,直到您实际调用draw_dice()为止。 To do this, you need to make the value of your dictionary items functions. 为此,您需要使字典项目的功能起作用。 The easiest way of doing this is to use lambda to define a one-line anonymous function: 最简单的方法是使用lambda定义单行匿名函数:

'dot1': lambda: c.create_oval(x, y, x + r, y + r, fill='black')

And when you iterate through your arguments, call the function: 当您遍历参数时,请调用该函数:

for arg in args:
     dots[arg]()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM