1

问题是在选择响应者之前需要考虑参数。到目前为止,这是我的尝试。

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 包含的所有功能。

4

5 回答 5

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
于 2009-01-26T03:07:59.243 回答
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)

which() 从选项中随机选择一个选项,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 来编写,但我会这样写,这样更清楚。

于 2009-01-26T03:09:31.143 回答
1

关于什么:

RandomResponder = [A, B, C]
RandomResponder[0].doSomething()   # returns A.doSomething()
RandomResponder[1].doSomething()   # returns B.doSomething()
RandomResponder[2].doSomething()   # returns C.doSomething()
# etc
于 2009-01-26T03:02:38.677 回答
0

如果您指定args(不带星号),它只是一个值列表(字符串)。同样,kwargs是匹配键(字符串)到值(字符串)的字典。

是我在谷歌搜索args kwargs之后发现的第一个结果。

编辑:我实际上不太清楚你在寻找什么,所以这只是一个猜测。

于 2009-01-26T02:01:44.180 回答
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 编码来操作类。

于 2009-01-26T02:32:02.920 回答