Python - Store function with parameters

感情迁移 提交于 2021-01-23 08:16:55

问题


I'm using Tkinter for a simple trivia game. There are several buttons, one for each answer, and I'd like to run a checkAnswer function with certain parameters when one is clicked.

If I used something like the following:

self.option1 = Button(frame, text="1842", command=self.checkAnswer(question=3, answer=2))

Then it would run checkAnswer and use what it returned (nothing).

Is there a simple way to store the parameters in the button constructor?


回答1:


This is exactly what functools.partial() is designed to do:

>>> import functools
>>> print_with_hello = functools.partial(print, "Hello")
>>> print_with_hello("World")
Hello World
>>> print_with_hello()
Hello

partial() returns a new function that behaves just as the old one, but with any arguments you passed in filled, so in your case:

import functools

...

self.option1 = Button(frame, text="1842", command=functools.partial(self.checkAnswer, question=3, answer=2))



回答2:


You could create a higher order function to wrap your checkAnswer function. This would allow you to return a function that wouldn't require any parameters, and therefore could be used as a callback.

For example:

def makeCheckAnswer(self, **kwargs)
    return lambda: self.checkAnswer(**kwargs)

This would make your button initialization:

self.option1 = Button(frame, text="1842", command=self.makeCheckAnswer(question=3, answer=2))



回答3:


By far easiest is just to use lambda in place

self.option1 = Button(frame, text="1842", 
    command=lambda: self.checkAnswer(question=3, answer=2))

Though, in a similar but a bit more complicated cases, you really should use a function factory such as

def answerCheckerFactory(self, question, answer):
    def checker():
        return self.checkAnswer(question, answer)

    return checker

    ...
    self.option1 = Button(frame, text="1842", 
        command=self.answerCheckerFactory(question=3, answer=2))

because it would make sure that you pass in correct arguments (not quetsion (sic) for example); notice the difference from functools.partial which allows you to mistype the function arguments and get an exception only when clicked on the button ;)

Also, hardcoding the questions / answers in the button code does not seem right...




回答4:


If you have functions that have specific parameters (that dont rely on things like text.get()) you can use wrappers for it, which would be the easiest way to do this, other than lambada functions. For example:

def option1wrapper():
    ClassName.checkAnswer(question=3,answer=2)
self.option1 = Button(frame, text="1842", command=option1wrapper)


来源:https://stackoverflow.com/questions/10692602/python-store-function-with-parameters

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!