2016-08-05 5 views
0

У меня есть объект, как:Как динамически генерировать методы для класса proxy?

class Foo(object): 
    def __init__(self,instance): 
     self.instance = instance 

с

>>> instance = SomeOtherObject() 
>>> f = Foo(instance) 

Я хочу быть в состоянии сделать

>>> f.some_method() 

и имеют следующий вызов,

>>> f.instance.some_method() 

Для ком по разным причинам я не могу просто связать атрибуты, как в приведенном выше. Мне нужно динамически создать функцию экземпляра на f с той же сигнатурой функции, что и встроенный instance. То есть, мне нужно сделать f.some_method(), а затем динамически создать экземпляр метода some_method для экземпляра f, когда он вызывается, который толкает some_method до внедренного объекта instance.

я надеюсь это сделал. Это для Python 2.7. Любая помощь оценивается.

+0

Чтобы создать 'Foo' в вашем коде, нужно передать экземпляр чего-либо другого в качестве аргумента, поэтому' f = Foo() 'приведет к ошибке. – martineau

ответ

3

Напишите метод __getattr__() для вашего прокси-класса. Это будет вызываться при доступе к атрибуту, который не существует в вашем экземпляре. Верните атрибут объекта с тем же именем (или оболочку, если вы настаиваете, но нет необходимости, если вы просто хотите вызвать метод содержащегося объекта и не нужно ничего делать). Бонус: работает с данными, а также с вызывающими.

def __getattr__(self, name): 
    return getattr(self.instance, name) 

Не работает с __ методами, однако.

1

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

class Test(object): 
    def some_method(self): 
     print 'original' 

import wrapt 

proxy = wrapt.ObjectProxy(Test()) 
proxy.some_method() 

print 

class TestWrapper(wrapt.ObjectProxy): 
    def some_method(self): 
     self.__wrapped__.some_method() 
     print 'override' 

wrapper = TestWrapper(Test()) 
wrapper.some_method() 

Это дает:

original 

original 
override 

поведение по умолчанию ObjectProxy класса является прокси все вызовы методов или атрибутов доступа. Обновление атрибутов через прокси-сервер также будет обновлять обернутый объект. Работы для специальных __ методов и много других вещей также.

Для получения дополнительной информации о wrapt см:

Конкретные сведения о прокси-объект может быть найден в:

Есть так много ловушек и ловушек с этим правильно, поэтому рекомендуется использовать wrapt, если сможете.

Смежные вопросы