2009-01-26 21 views
1

問題是需要在選擇響應者之前考慮參數。這是我迄今的嘗試。需要在Python類中路由實例調用

from responders import A, B, C 

class RandomResponder(object) 
    def init(self, *args, *kwargs): 
     self.args = args 
     self.kwargs = kwargs 

    def __getattr__(self, name): 
     # pick a responder based on the args the function was called with 
     # I don't know how to do this part 
     # for sake of argument lets the args a function was called with lead me to pick responder A 
     r = A 
     responder = r(*self.args, **self.kwargs) 
     return responder.__getattr__(name) 

的預期效果是:

r = RandomResponder() 
r.doSomething(1) 
#returns A.doSomething() 
r.doSomething(2) 
#returns B.doSomething() 
r.doSomething(3) 
#return C.doSomething() 
r.doSomethingElse(1) 
#returns A.doSomethingElse() 
r.doSomethingElse(2) 
#returns B.doSomethingElse() 
r.doSomethingElse(3) 
#returns C.doSomethingElse() 

我不知道提前包含與應答A,B和C

+0

你很難清楚你想要做什麼,你能提供更多信息嗎? (我也會澄清標題) – 2009-01-26 02:01:38

+0

請用更多的事實更新你的問題;評論一個答案不如解決你的問題。 – 2009-01-26 02:48:47

回答

2

嘗試這種情況:

class RandomResponder(object): 
    choices = [A, B, C] 

    @classmethod 
    def which(cls): 
     return random.choice(cls.choices) 

    def __getattr__(self, attr): 
     return getattr(self.which(), attr) 

其中()隨機選擇的選擇的選項,並且其GETATTR用來獲取該屬性。

編輯:它實際上看起來像你想要更像這樣的東西。

class RandomResponder(object): 
    choices = [A, B, C] 

    def __getattr__(self, attr): 
     # we define a function that actually gets called 
     # which takes up the first positional argument, 
     # the rest are left to args and kwargs 
     def doCall(which, *args, **kwargs): 
      # get the attribute of the appropriate one, call with passed args 
      return getattr(self.choices[which], attr)(*args, **kwargs) 
     return doCall 

這可以寫成使用lambda,但我會留下這樣,所以它更清晰。

0

的所有功能,如果指定args(沒有星號),它只是一個值列表(字符串)。同樣,kwargs是一個將鍵(字符串)與值(字符串)進行匹配的詞典。

This是我在谷歌搜索args kwargs後發現的第一個結果之一。

編輯:我其實不知道你在找什麼,所以這只是一個猜測。

0

你想要做這個嗎?

from responders import A, B, C 

class RandomResponder(object) 

    def pickAResponder(self, someName): 
     """Use a simple mapping.""" 
     return { 'nameA': A, 'nameB': B, 'nameC': C }[someName] 

    def __init__(self, *args, *kwargs): 
     self.args = args 
     self.kwargs = kwargs 

    def __getattr__(self, name): 
     """pick a responder based on the args[0]""" 
     r = self.pickAResponder(self.args[0]) 
     responder = r(*self.args, **self.kwargs) 
     return responder.__getattr__(name) 

您的響應者類(A,B,C)只是對象。您可以使用映射,列表,if語句來操作類,無論您在pickAResponder方法中使用哪種Python編碼。

+0

關閉,但我不想使用__init__中的參數,我想使用該參數被調用的參數。 – 2009-01-26 02:35:30

+0

請更新您的問題與其他事實。 – 2009-01-26 02:48:01

1

什麼:

RandomResponder = [A, B, C] 
RandomResponder[0].doSomething() # returns A.doSomething() 
RandomResponder[1].doSomething() # returns B.doSomething() 
RandomResponder[2].doSomething() # returns C.doSomething() 
# etc 
3

當你做到這一點

r.doSomething(1) 

發生的事情是,爲了:

  • r.__getattr__被調用,並返回一個對象
  • 這使用參數「1」調用對象

在當__getattr__被調用的時候,你有沒有辦法知道對象返回哪些參數是得到調用,或者即使它要在所有稱爲...

因此,爲了獲得您想要的行爲,__getattr__必須返回一個可調用的對象,該調用對象根據參數決定其自身,它調用的是。例如

from responders import A, B, C 

class RandomResponder(object): 
    def __getattr__(self, name): 
     def func(*args, **kwds): 
      resp = { 1:A, 2:B, 3:C }[args[0]] # Decide which responder to use (example) 
      return getattr(resp, name)()   # Call the function on the responder 
     return func