2016-09-22 2 views
0

Например у меня есть что-то вроде этого:Перегрузки и обертывание метод поля родительского класса в Python

class A(object): 
    def __init__(self): 
     pass 

    def foo(self, a, b, c): 
     return a + b + c 


class B(object): 
    def __init__(self): 
     self.b = A() 


def wrapper_func(func): 

    def wrapper(self, *args, **kwargs): 
     return func(self, a=3, *args, **kwargs) 

    return wrapper 


class C(B): 
    def __init__(self): 
     pass 

    @wrapper_func 
    def ??? 

Можно ли как некоторые перегрузки, а затем оберните метод foo поля родительского B класса в Python без наследования от класса A? Мне нужна оболочка, потому что у меня есть разные методы с одинаковыми аргументами, но в то же время мне приходится сохранять исходные методы класса B native (помимо перегрузки).

ответ

1

Initialize C «s родительского класс, используя super, а затем передать все параметры в foo метода экземпляра составленного класса A() через унаследованной атрибут b класса C:

def wrapper_func(func): 
    def wrapper(self, *args, **kwargs): 
     kwargs['a'] = 3 
     return func(self, *args, **kwargs) 
    return wrapper 


class C(B): 
    def __init__(self): 
     super(C, self).__init__() 

    @wrapper_func 
    def bar(self, *args, **kwargs): 
     return self.b.foo(*args, **kwargs) # access foo via attribute b 

Trial:

c = C() 
print(c.bar(a=1, b=2, c=3)) 
# 8 -> 3+2+3 

Чтобы сделать вызов декорированной функции через c.b.foo, патчc.b.foo метод с новым bar методом:

class C(B): 
    def __init__(self): 
     super(C, self).__init__() 
     self._b_foo = self.b.foo 
     self.b.foo = self.bar 

    @wrapper_func 
    def bar(self, *args, **kwargs): 
     return self._b_foo(*args, **kwargs) 

Trial:

c = C() 
print(c.b.foo(a=1, b=2, c=3)) 
# 8 -> 3+2+3 
+0

Так что способ вызова из обернутого метод будет таким, как 'c.bar (1, 2, 3)', но мне нужно то же имя вызова, что и 'cbfoo (1, 2, 3)'. Но я думаю, это невозможно ...? – NULL

+0

Почему 'c.b.foo (1, 2, 3)'? Это вызовет только метод 'foo'' A' –

+0

Да, в основном это вызовет метод 'foo'' A', но я имею в виду перегрузку и упаковку, например 'def b.foo (self): ...' , для вызова того же 'cbfoo()' вместо другого имени, как 'c.bar()'. И это невозможно, я думаю? – NULL

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