通过dict调用函数移交

时间:2019-02-04 14:49:04

标签: python-3.x

我有一个线程控制器,可以构建一个插件对象和一个ui对象。 addob对象具有getUIOptions方法,该方法返回一个用户可以选择的选项。

EXIT_OPTION = {
        "text": "Exit Program",
        "function": "close()",
        "controller": self,
        "trigger": "x",
        }

用户界面显示文本并由用户选择。选定的选项提供给控制器,并且必须将函数调用为eval()在dict中引用的“控制器”对象。

我尝试使用eval()函数,但我认为该函数的调用存在一些问题。

类控制器(threading.Thread):

def __init__(self):
    threading.Thread.__init__(self)
    self.addon = addon(self)
    UIelement = self.addon.getUIOptions()
    #create UI
    self.UI = UI(self)
    #Register all UI Element and the object
    self.UI.addFeature(UIelement, self.addon)

    #blocker to sleep the thread
    self.blocker = threading.Event()

    #dict like the EXIT_OPTION
    self.__trigger = {}

def run(self):
    self.controllerUI.start()
    self.blocker.wait()
    while self.blocker.is_set():
        self.__uiEvent()       
        self.__trigger = {} #clear Trigger
        self.blocker.clear()
        self.blocker.wait()

def __uiEvent(self):
    """
    If the user select an option the controller has to execute it.
    Trigger is set by setTrigger() and the thread is waked up by 
    blocker.set()
    """
    trigger = self.__trigger
    if bool(trigger) is True:

        # No controller -> method is part of Controller
        if trigger['controller'] is None:
            function = trigger['function']
        # Methode is part of object trigger['controller']
        else:
            function = trigger['controller'].trigger['function']
        eval(function)
    else:
        print("Error: Trigger is empty")

类UI(threading.Thread):

__FEATURES = []

def __init__(self, caller=None):
    threading.Thread.__init__(self)
    self.caller = caller

def addFeature(self, feature, controller=None):
    feature['controller'] = controller
    index = len(UI.__FEATURES)
    feature['trigger'] = str(index)
    UI.__FEATURES.append(feature)

def run(self):
    while True:
        selection = selectMenu(UIController.__FEATURES, '### TrafficSimulator ###', EXIT_OPTION)
        self.caller.setTrigger(selection) #set dict to controller
        self.caller.blocker.set()         #wakeup controller

def selectMenu(self, selectableList, label, additionOption = None):
    """
    Returns the selected element of the list if valid selection is 
    given
    """
    while True:
        print('\n' + label + '\n')
        #make one dict
        if type(selectableList) is list and additionOption not in selectableList :
            selectableList.append(additionOption)
        print(selectableList)
        selection = input('\nSelection: ')
        for option in selectableList:
            if str(option['trigger']) == str(selection):
                return option
        print('Error: No valid selection')

class addon():

def getUIOptions(self):

    UI_OPTIONS = {
        "text": "Do Something",
        "controller": self,
        "function": "doSomething()",
        "trigger": "a",
    } 
    return UI_OPTIONS

def doSomething():
    print("Something done")

必须将控制器调用由dict ['controller']引用的对象的方法dict ['function']。

0 个答案:

没有答案