从QMainWindow中使用变量名调用Python函数

从QMainWindow中使用变量名调用Python函数,python,eval,qmainwindow,Python,Eval,Qmainwindow,我试图找到一种高效、安全的方法,根据用户输入的事务名称调用不同的函数。有100多个不同的交易。100个“如果”就行了,不过,我想找到一种更有效的方式来调用事务。“eval”可以做到这一点,但我读到不应该使用它,因为用户可以输入任何事务名称 from operator import methodcaller import sys from PyQt5.QtWidgets import (QMainWindow,QToolBar,QLineEdit,

我试图找到一种高效、安全的方法,根据用户输入的事务名称调用不同的函数。有100多个不同的交易。100个“如果”就行了,不过,我想找到一种更有效的方式来调用事务。“eval”可以做到这一点,但我读到不应该使用它,因为用户可以输入任何事务名称

from operator import methodcaller
import  sys
from    PyQt5.QtWidgets     import (QMainWindow,QToolBar,QLineEdit,
                                    QLabel, QApplication)
def one():
        print ("1")

def two():
        print ("2")

def three():
        print("3")

class main_menu(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        menuBar = self.menuBar()
        self.ToolBar = QToolBar()
        self.ToolBar.setMovable(False)
        self.addToolBar(self.ToolBar)
        self.tcode = QLineEdit(maxLength=5)
        self.tcode.returnPressed.connect(self.tcode_action) 
        self.ToolBar.addWidget(QLabel("  Transaction : "))
        self.ToolBar.addWidget(self.tcode)

    def tcode_action(self):
##        if self.tcode.text() == "one":
##                one()
##        if self.tcode.text() == "two":
##                two()
##        if self.tcode.text() == "three":
##                three()

##        eval(self.tcode.text()+"()")        

def main(args):
    app                 = QApplication(sys.argv)
    mm = main_menu()
    mm.show()
    sys.exit(app.exec_())
if __name__=="__main__":
    main(sys.argv)



在python中,可以通过访问全局变量。 您可以使用:

def tcode_动作(自身):
fn=globals().get(self.tcode.text())
如果fn:
fn()
其他:
打印(“无效输入”)

一个选项可以是使用
QComboBox
来限制功能集。您还可以使用
Enum
枚举有效函数

从枚举导入枚举
从functools导入部分
#函数定义
def fcn_1(x):
打印('F1')
def fcn_2(x):
打印('F2')
#有效函数枚举
#必须以分部形式包装函数,以便它们不被定义为方法。
#有关更多详细信息,请参阅下面的帖子。
类有效函数(枚举):
回波=部分(fcn_1)
增量=部分(fcn_2)
#函数选择组合框
cb=QComboBox()
cb.addItem(‘Echo’)
cb.AddItem(‘增量’)
#连接信号机
def调用函数():
fcn=有效函数[cb.currentText()]
fcn()
cb.currentIndexChanged.connect(调用函数)
注意:我还没有调试这段代码


我现在将使用此代码执行此操作:

def tcode_action(self):
    try:
            func = getattr(self,self.tcode.text())
            func()
    except:
            pass

对此有何评论?

旁注,因为Anurag Regmi已经回答了这个问题:始终使用
if-->elif-->else
和大量if's。如果您不这样做,即使在已经匹配If之后,它也会执行其余的If…注意,使用此选项会有一些危险,因为它可能会导致任意代码执行(例如,用户输入
main
)。更安全的方法是使用dict,如中所示,但如果有100多个不同的函数可以调用,这可能会是一个后遗症…在您的原始代码中,函数不是类的成员,因此调用
getattr
将不起作用,您应该使用@Anurag Regmi的代码使用globals,或者将函数移动到类中。对,我将函数移动到类中。