2016-09-22 1 views
0

Zum Beispiel habe ich so etwas wie diese:Overloading und Wickelverfahren des Bereichs der übergeordneten Klasse in 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 ??? 

Ist es möglich, einige, wie Überlastung und dann wickelt Methode foo des Feldes der Eltern B Klasse in Python ohne erbt von Klasse A? Ich brauche den Wrapper in der Tat, weil ich die verschiedenen Methoden mit den gleichen Argumenten habe, aber gleichzeitig muss ich die ursprünglichen Methoden der Klasse B nativ speichern (neben dem Überladen).

Antwort

1

Initialize C ‚s Elternklasse super verwendet und dann alle Parameter übergeben an die foo Methode der zusammengesetzten Klasseninstanz A() über die vererbten Attribut b der Klasse 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 

Versuchs:

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

Um den Anruf an die dekorierten Funktion über c.b.foo, machen Patch die c.b.foo Methode mit der neuen bar Methode:

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) 

Versuch:

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

So auf diese Weise Berufung eingewickelt Methode wird so sein 'c.bar (1, 2, 3)', aber ich brauche den gleichen Rufnamen wie 'cbfoo (1, 2, 3)' zu sein. Aber ich denke, das ist nicht möglich ...? – NULL

+0

Warum 'c.b.foo (1, 2, 3)'? Das nennt man nur die 'foo' Methode von' A' –

+0

Yep, im Grunde wird das die 'foo' Methode von' A' heißen, aber ich meine das Überladen und Umbrechen wie 'def b.foo (self): ...' , um das gleiche 'cbfoo()' anstelle eines anderen Namens wie 'c.bar()' aufzurufen. Und das ist nicht möglich, denke ich? – NULL

Verwandte Themen