Нужно направить вызовы экземпляра внутри класса Python - PullRequest
1 голос
/ 26 января 2009

Проблема заключается в необходимости учитывать аргументы перед выбором респондента. Вот моя попытка.

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.

Ответы [ 5 ]

3 голосов
/ 26 января 2009

Когда вы делаете это

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
2 голосов
/ 26 января 2009

Попробуйте это:

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

Это можно написать с помощью лямбды, но я просто оставлю это так, чтобы было понятнее.

1 голос
/ 26 января 2009

А как же:

RandomResponder = [A, B, C]
RandomResponder[0].doSomething()   # returns A.doSomething()
RandomResponder[1].doSomething()   # returns B.doSomething()
RandomResponder[2].doSomething()   # returns C.doSomething()
# etc
0 голосов
/ 26 января 2009

Вы пытаетесь это сделать?

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 и любой другой кодировки Python, которую вы хотите использовать в методе pickAResponder.

0 голосов
/ 26 января 2009

Если указать args (без звездочки), это просто список значений (строк). Точно так же, kwargs является Dict соответствия ключей (строк) значениям (строкам).

Это - один из первых результатов, которые я нашел после поиска в Google args kwargs .

Редактировать: На самом деле я не совсем понимаю, что вы ищете, так что это всего лишь предположение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...