Декорирование метода DBUS - PullRequest
       13

Декорирование метода DBUS

2 голосов
/ 20 февраля 2011

Я пытаюсь объединить вызовы асинхронных методов DBUS с задержанными Twisted, но я сталкиваюсь с проблемой при настройке обычного декоратора методов службы DBUS для этого.

Чтобы использовать подход асинхронных обратных вызовов DBUS,вы бы сделали:

class Service(dbus.service.Object):

    @dbus.service.method(INTERFACE, async_callbacks=('callback', 'errback'))
    def Resources(self, callback, errback):
        callback({'Magic' : 42})

В нескольких местах я просто оборачиваю эти два метода в Deferred, поэтому я подумал, что создам декоратор, чтобы сделать это для меня:

def twisted_dbus(*args, **kargs):
    def decorator(real_func):

        @dbus.service.method(*args, async_callbacks=('callback', 'errback'), **kargs)
        def wrapped_func(callback, errback, *inner_args, **inner_kargs):
            d = defer.Deferred()
            d.addCallbacks(callback, errback)
            return real_func(d, *inner_args, **inner_kargs)

        return wrapped_func

    return decorator

class Service(dbus.service.Object):

    @twisted_dbus(INTERFACE)
    def Resources(self, deferred):
        deferred.callback({'Magic' : 42})

Это, однако, не работает, так как метод связан и принимает первый аргумент, что приводит к следующей трассировке:

$ python service.py 
Traceback (most recent call last):
  File "service.py", line 25, in <module>
    class StatusCache(dbus.service.Object):
  File "service.py", line 32, in StatusCache
    @twisted_dbus(INTERFACE)
  File "service.py", line 15, in decorator
    @dbus.service.method(*args, async_callbacks=('callback', 'errback'), **kargs)
  File "/usr/lib/pymodules/python2.6/dbus/decorators.py", line 165, in decorator
    args.remove(async_callbacks[0])
ValueError: list.remove(x): x not in list

I может добавить дополнительный аргумент квнутренняя функция там, вот так:

def twisted_dbus(*args, **kargs):
    def decorator(real_func):

        @dbus.service.method(*args, async_callbacks=('callback', 'errback'), **kargs)
        def wrapped_func(possibly_self, callback, errback, *inner_args, **inner_kargs):
            d = defer.Deferred()
            d.addCallbacks(callback, errback)
            return real_func(possibly_self, d, *inner_args, **inner_kargs)

        return wrapped_func

    return decorator

Но это кажется ... ну, глупым.Особенно, если по какой-то причине я хочу экспортировать не связанный метод.

Так можно ли заставить этот декоратор работать?

1 Ответ

0 голосов
/ 20 февраля 2011

Почему это глупо? Вы уже предполагаете, что знаете, что первым позиционным аргументом (после себя) является Отложенный. Почему глупее предполагать, что вы знаете, что настоящий аргумент первой позиции - это я?

Если вы также хотите поддерживать свободные функции, напишите другой декоратор и используйте его, когда вы знаете, что аргумент self не приходит.

...