Простой объект регистрации - PullRequest
0 голосов
/ 16 ноября 2011

У меня есть какой-то модуль python, который имеет класс ModuleClass, и я не могу изменить этот класс.

Теперь я хочу иметь возможность проксировать методзвонки и добавить определенные функции ведения журнала.Я предполагаю, что это должно быть сделано через объект пересылки и соответствующий прокси (following Effective Java, Item 16).

Псевдокод python, который я придумал, выглядит следующим образом.

(Извините, у меня действительно плохо получается python, и я был бы признателен, если бы вы могли указать здесь ошибки).

# This is what I've got in my module and this code cannot be changed.
class ModuleClass(object):
    def method1(self):
        # Some implementation
        pass()
    def method2(self):
        # Some implementation
        pass()

# Simple forwarding proxy to avoid the situation described in Effective Java, I16

# However, in Java this class would usually be extending the interface, not
# inheriting 'ModuleClass' (I'm confused and don't know how to do the same
# in python).

class ForwardingModuleClass(ModuleClass):
    # 'proxifiedObject' is 
    def __init__(self, proxifiedObject):
        self.proxifiedObject = proxifiedObject

    # Overriding the first method
    def method1(self):
        return self.proxifiedObject.method1()

    # Same for method2...

class LoggingModuleClass(ForwardingModuleClass):
    # 'classThatActuallyDoesStuff' should be an instance of 'ModuleClass'.
    def __init__(self, classThatActuallyDoesStuff):
        # Sorry for my bad knowledge of python syntax, but
        # I assume I can initialize the superclass here using
        # the supplied 'ModuleClass' instance.
        super(classThatActuallyDoesStuff)

    # Overriding the first method.
    def method1(self):
        print("Yay! This 'method1' really logs something!")
        return super.method1()

    # Overriding the second method.
    def method2(self):
        print("Yay!!!! This 'method2' also does something cool!")
        return super.method2()

Теперь, я думаю, правильно написано, что это будет работать, и у меня будет прокси-сервер регистрации для моего начального ModuleClass.

Если есть ошибки или если это не pythonish, пожалуйста, укажите это.

Кроме того, Я подозреваю, что это легко сделать с помощью decorators, , но, к сожалению, я не могу придумать подходящий путь и понятия не имею, что может произойтиесли ModuleClass уже имеет некоторые методы декораторов.

Не могли бы вы помочь мне и здесь?

Ответы [ 3 ]

2 голосов
/ 16 ноября 2011

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

class LoggingFoo(object):
    def __init__(self, *args, **kwargs):
        self.obj = Foo(*args, **kwargs)

    def method1(self):
        # ...
        return self.obj.method1()

    def method2(self):
        # ...
        return self.obj.method2()
2 голосов
/ 16 ноября 2011

Как насчет прямого подкласса ModuleClass напрямую:

import logging

logger=logging.getLogger(__name__)

class LoggingModuleClass(ModuleClass):
    def method1(self):
        logger.info("Yay! This 'method1' really logs something!")
        return super(LoggingModuleClass,self).method1()
    def method2(self):
        logger.info("Yay! This 'method2' also does something cool!")
        return super(LoggingModuleClass,self).method2()

logging.basicConfig(level=logging.DEBUG)

(я добавил код, чтобы показать базовые настройки для ведения журнала способом Python).

1 голос
/ 16 ноября 2011

Если вы ищете решение для декоратора, вам следует взглянуть на ответ этого поста: Python decorator заставляет функцию забыть, что она принадлежит классу

Вы указали, чтоВы хотите избежать «нежелательных сообщений» (в случае, если method1 вызывает method2), тогда я бы предложил вам выбрать решение, предоставляемое Cat Plus, в противном случае я бы выбрал операторов.

...