2013-07-30 2 views
0

Я ищу, чтобы украсить класс «вызываемый» (тот, который определил метод __call__), чтобы я мог начать фоновое обслуживание до того, как вызывается __init__ и обрабатывает аргументы, переданные до того, как он сам вызван, чтобы включить детали сервис, который был запущен.Как я могу украсить класс «вызываемый» с помощью декоратора класса?

Так, например:

@init_service # starts service on port 5432 
class Foo(object): 
    def __init__(self, port=9876): 
    # init here. 'port' should now be `5432` instead of the original `9876` 

    def __call__(self): 
    # calls the background service here, using port `5432` 

func = Foo(port=9876) 
... 
result = func() 

Класс init_service будет иметь атрибут класса с номером порта, так что в дальнейшем сервис может быть выключению.

+0

Это не имеет ничего общего с классом быть отозван. –

ответ

2

Вы пытаетесь исправить метод __init__; тот факт, что есть метод __call__, также не имеет здесь никаких шансов.

Вы обычно украшаете метод __init__, используя обычный (функциональный) декоратор; если вы быть_наст использовать класс декоратор, а затем использовать один, что подкласс декорированного класса:

def init_service(cls): 
    class InitService(cls): 
     def __init__(self, port='ignored'): 
      super(InitService).__init__(5432) 

    return InitService 
+0

Есть ли способ определить класс вне функции init_service (он довольно велик из-за методов инициализации службы), а затем переопределить, какой объект он наследует из функции init_service? –

+0

@unpluggd: вам нужен динамический класс, который определяет наследование. Это может быть класс-оболочка, который просто выполняет класс WrapperInitService (RealInitServiceClass, cls) ', где' WrapperInitService' находится за пределами декоратора. У этого есть некоторые предостережения (в основном для того, чтобы использовать 'super()' для всего, что вы переопределяете), но он должен просто работать иначе. –