[英]Python3: use exec() to create a function
I am using tkinter to create an app and currently I made a lot of buttons so I need to bind all buttons with different command, I will like to use exec()
to create functions.我正在使用 tkinter 创建一个应用程序,目前我制作了很多按钮,所以我需要用不同的命令绑定所有按钮,我想使用
exec()
来创建函数。
strategy=None
exec("global commandbutton"+str(len(strategicpoint)+1)+"\ndef commandbutton"+str(len(strategicpoint)+1)+"():\n\tglobal strategy\n\tstrategy="+str(len(strategicpoint)))
commandline=eval('commandbutton'+str(len(strategicpoint)+1))
imgx=tk.Button(win,image=towert,command=commandline)
for cleaner solutions:对于更清洁的解决方案:
global commandbutton{...}
def commandbutton{...}():
global strategy
strategy={...}
I want my code run like above and it runs, but later I call the command and test to print(strategy)
, (I have clicked the button/invoked the command) it prints None
when I want it to print something else.我希望我的代码像上面一样运行并运行,但后来我调用命令并测试
print(strategy)
,(我点击了按钮/调用了命令)当我想要它打印其他东西时它打印None
。
There is absolutely no need to use exec()
or eval()
here.这里绝对不需要使用
exec()
或eval()
。
exec
, using a closure, or just by binding the parameter in a lambda function or functools.partial()
.exec
的绑定参数创建函数,使用闭包,或者仅通过在 lambda 函数或functools.partial()
绑定参数。 So if you have a loop with an incrementing strategicpoint
value, I'd just do this:因此,如果您有一个具有递增
strategicpoint
值的循环,我会这样做:
def set_strategy(point):
global strategy
strategy = point
buttons = []
for strategicpoint in range(1, number_of_points + 1):
imgx = tk.Button(win, image=towert, command=lambda point=strategicpoint: set_strategy(point))
buttons.append(imgx)
The lambda point=...
part binds the current loop value as a default value for the point
argument of the new function object that lambda
creates. lambda point=...
部分将当前循环值绑定为lambda
创建的新函数对象的point
参数的默认值。 When that function is called without arguments (as would be done when clicking the button), then the new function uses the integer value that was assigned to strategicpoint
at the time, to call set_strategy(point)
.当该功能被称为不带参数(如将点击该按钮时完成),那么新的函数使用被分配到整数值
strategicpoint
的时候,打电话给set_strategy(point)
。
You can also use a closure, a local variable in an outer function, that an inner function makes use of.您还可以使用内部函数使用的闭包,即外部函数中的局部变量。 Nested, inner functions inside an outer function are created each time you call the outer function, so they are separate from other function objects created by the same outer function:
每次调用外部函数时都会在外部函数内创建嵌套的内部函数,因此它们与由同一外部函数创建的其他函数对象分开:
def create_strategy_command(strategypoint):
def set_strategy():
global strategy
strategy = strategypoint
return set_strategy
then when creating your buttons, use:然后在创建按钮时,使用:
imgx = tk.Button(win, image=towert, command=create_strategy_command(strategicpoint))
Note that calling the create_strategy_command()
function returns a new function here, used as the button command.请注意,调用
create_strategy_command()
函数会在此处返回一个新函数,用作按钮命令。
Disclaimer: I haven't tested this.免责声明:我没有测试过这个。
Use a dictionary to store all your functions, as such:使用字典来存储您的所有函数,例如:
option = "default"
def change_option(target):
global option
option = target
def f1():
print("foo")
def f2():
print("bar")
my_functions = {
"select1": f1,
"select2": f2
"default": None
}
imgx=tk.Button(win,image=towert,command=my_functions[option]) # None
swapper = tk.Button(win, image=towert, lambda: change_option("select2")) # button to change the command if you want it
imgx=tk.Button(win,image=towert,command=my_functions[option]) # print("bar")
change_option("select1")
imgx=tk.Button(win,image=towert,command=my_functions[option]) # print("foo")
You could probably get by without using a dictionary, but in my opinion this is rather clean.你可能可以不使用字典,但在我看来这是相当干净的。 Don't ever use exec() or eval(), unless you absolutely know what security concerns it has, you know the product wont be used on another machine, or you really don't have another choice.
永远不要使用 exec() 或 eval(),除非你完全知道它有什么安全问题,你知道该产品不会在另一台机器上使用,或者你真的别无选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.