2017-08-17 68 views
2

這裏自動是我的情況:如何派遣一個方法調用多個處理程序在Python

我有這樣一個類:

class Handler: 
    def __init__(self, name): 
     self.name = name 

    def gogo(self, input): 
     print("My name is %s and I got %s" % (self.name, input)) 

我想實現的是這樣的:

dispatcher = Dispatcher(Handler("who"), Handler("what")) 
dispatcher.gogo("food") 

>> "My name is who and I got food" 
>> "My name is what and I got food" 

我的第一次嘗試是創建一個Dispatcher類,它在其__init__方法中創建自己的方法。在這種情況下,Dispatcher的每個方法都會在不同的處理程序上觸發相同的方法。缺點是,如果在調度程序初始化後之後的處理程序中添加了任何新方法,則它將不起作用。

所以我的第二次嘗試是有一個__getattr__方法生成的新方法每次調用時調用的處理方法,所以基本上是這樣的:

def __getattr__(self, item): 
    methods = [] 
    for destination in self._destinations: 
     if hasattr(destination, item): 
      destination_method = getattr(destination, item) 

      # if the argument is not callable, we are not interested, we cannot do anything with it 
      # Maybe we should even raise an error here? 
      if callable(destination_method): 
       methods.append(destination_method) 

    # If none of the destinations had a method for this name, we cannot do anything and should raise 
    if len(methods) == 0: 
     raise NotImplementedError("No method found for property %s" % item) 

    # Create a wrapper around the methods that we detected that will just pass the arguments 
    def new_method(*args, **kwargs): 
     for method in methods: 
      method(*args, **kwargs) 

    return new_method 

這一個缺點是,它產生每次都有一種新的方法,一般來說這並不是很好。另外,它只是覺得不太好,可能容易出錯(例如調度器很不透明,當你得到它時,你不能確定哪些方法可用或不可用)。

我想要實現的方法的數量是已知的,所以理論上我可以爲所有處理程序提供一個基類,這些處理程序將包含由它們實現的每個方法潛在

我正在尋找一個解決方案,儘可能優雅,不涉及dispatcher.gogo("food")大開銷,因爲它應該是一個非常簡單的系統。

回答

1

爲什麼不把分派器方法從本地範圍移動到實例級別?

class Dispatcher(): 

    def __dispatch(self, *args , **kwargs): 
     for method in self.__methods: 
      method(*args, **kwargs) 

    def __getattr__(self, item): 
     self.__methods = [] 
     … 
       if callable(destination_method): 
        self.__methods.append(destination_method) 
     … 
     return self.__dispatch 
相關問題