是否可以将字符串转换为函数对象?
Posted
技术标签:
【中文标题】是否可以将字符串转换为函数对象?【英文标题】:Is it possible to turn a string into a function object? 【发布时间】:2020-10-14 06:20:28 【问题描述】:我正在使用 Tkinter 和 matplotlib 创建一个小型排序数组项目。我的 Tkinter GUI 有一个列表框,我想用它来选择所需的排序算法。我正在使用 matplotlib 的 FuncAnimation() 重复遍历我选择的排序函数并为其设置动画。 FuncAnimation() 将您决定用作参数的函数的名称。我想为参数分配一个变量,我可以将它重新分配给我想使用的任何函数的名称。
我认为问题在于 listbox.get(ANCHOR) 给了我一个字符串,而 FuncAnimation 想要某种函数对象。我已经研究了将字符串转换为函数对象或可调用函数的可能方法,但我要么不理解,要么找不到任何东西。
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from Tkinter import *
import Tkinter as tk
#example of one of the sorting functions.
def Quick_Sort(i):
global arr # I don't know why I have to use a globalized variable. Wouldn't let me pass it arr
n=len(arr)
less_than=[]
equal_to=[]
greater_than=[]
if i in range(1,n-1):
if arr[i-1]>arr[i] or arr[i]>arr[i+1]:
#break into sub arrays
pivot=arr[i]
del arr[i]
for y in range(0,n-1):
plt.clf()
if arr[y]< pivot:
less_than.append(arr[y])
if arr[y]==pivot:
equal_to.append(arr[y])
elif arr[y]>pivot:
greater_than.append(arr[y])
del arr[:]
less_than.append(pivot)
arr=less_than + equal_to + greater_than
del less_than[:], greater_than[:], equal_to[:]
plt.bar(arr_ind,arr)
fig.canvas.draw()
elif i>n-1:
print("'i' is out of range. Exiting program.")
print ("Final array is ", arr)
sys.exit()
return i
def choose_and_run():
choice=listbox.get(ANCHOR)
fig=plt.figure()
ax=fig.add_axes([0,0,1,1])
fill_array(arr,arr_ind,arr_size)
fig.canvas.draw()
anim=animation.FuncAnimation(fig,choice,interval=50)
plt.show()
#---TKINTER STUFF-------
window=tk.Tk()
window.title("Sorting Arrays")
window.geometry("150x00")
listbox=tk.Listbox(window)
# Algorithm Options
listbox.insert(1,"Bubble_Sort")
listbox.insert(2,"Insertion_Sort")
listbox.insert(3,"Quick_Sort")
listbox.insert(4,"Selection_Sort")
listbox.pack()
# Select and run button
button1=tk.Button(window,text="Get and Go",command=choose_and_run).pack()
window.mainloop()
希望这是足够的信息。任何帮助表示赞赏。
【问题讨论】:
【参考方案1】:您通常不会直接将字符串转换为函数名,即使使用 Python 几乎任何事情都是可能的。但是,函数只是对象,所以只需使用 dict:
chosenfunc = "Bubble_Sort":Bubble_Sort, "Insertion_Sort":Insertion_Sort,
"Quick_Sort":Quick_Sort, "Selection_Sort":Selection_Sort
selection=listbox.get(ANCHOR)
choice = chosenfunc[selection]
【讨论】:
谢谢,它有效!没有意识到我可以使用字典。 还有一个额外的好处是 GUI 选择项不必匹配它们正在调用的函数名称。因此,您可以在用户的选择中删除下划线。 (只要确保你的字典键匹配!!)【参考方案2】:您可以使用locals()
或globals()
分别访问带有本地或全局符号表的字典。如果你的函数在同一个模块中声明,你可以使用它。
如果没有,您可以在模块对象上使用getattr
:
import module
dynamically_imported_method = getattr(module, 'bar')
dynamically_import_method()
【讨论】:
我做了类似这样的讨厌的事情来创建基于全局字典中的函数名称的函数选项。它使添加新功能就像定义函数一样简单,但我认为这比问题的优点更深一些。也许定义一个包含所有函数的类,并在类上使用 dir() 可能会好一点。以上是关于是否可以将字符串转换为函数对象?的主要内容,如果未能解决你的问题,请参考以下文章
是否有内置的 Javascript 函数可以将一个月的文本字符串转换为等值的数字?
是否有任何通用 Parse() 函数可以使用解析将字符串转换为任何类型?