Chciałbym zawrzeć kilka metod klasowych w Pythonie z tym samym opakowaniem.Zawijanie wywołań do metod klasy Pythona
Koncepcyjnie to będzie wyglądać mniej więcej tak w najprostszym scenariuszu:
x = 0 # some arbitrary context
class Base(object):
def a(self):
print "a x: %s" % x
def b(self):
print "b x: %s" % x
class MixinWithX(Base):
"""Wrap"""
def a(self):
global x
x = 1
super(MixinWithX, self).a()
x = 0
def b(self):
global x
x = 1
super(MixinWithX, self).a()
x = 0
Oczywiście, gdy istnieje więcej sposobów niż a
i b
, to staje się bałagan. Wygląda na to, że powinno być coś prostszego. Oczywiście x
mogą być modyfikowane w dekoratora ale nadal kończy się o długą listę śmieci, które zamiast powyższych wygląda następująco:
from functools import wraps
def withx(f):
@wraps(f) # good practice
def wrapped(*args, **kwargs):
global x
x = 1
f(*args, **kwargs)
x = 0
return wrapped
class MixinWithX(Base):
"""Wrap"""
@withx
def a(self):
super(MixinWithX, self).a()
@withx
def b(self):
super(MixinWithX, self).b()
Myślałem o użyciu __getattr__
w wstawek, ale oczywiście od metody, takie jako a
i b
są już zdefiniowane, to nigdy nie jest wywoływane.
Myślałem również o użyciu __getattribute__
, ale zwraca atrybut, nie owijając połączenia. Przypuszczam, że __getattribute__
może zwrócić zamknięcie (przykład poniżej), ale nie jestem pewien, jak brzmi projekt. Oto przykład:
class MixinWithX(Base):
# a list of the methods of our parent class (Base) that are wrapped
wrapped = ['a', 'b']
# application of the wrapper around the methods specified
def __getattribute__(self, name):
original = object.__getattribute__(self, name)
if name in wrapped:
def wrapped(self, *args, **kwargs):
global x
x = 1 # in this example, a context manager would be handy.
ret = original(*args, **kwargs)
x = 0
return ret
return wrapped
return original
To przyszło mi do głowy, że może być coś wbudowane w Pythonie, które mogą zmniejszyć potrzebę ręcznego powielania każdą metodę klasy nadrzędnej, która ma być opakowane. A może zamknięcie w __getattribute__
jest właściwym sposobem na zrobienie tego. Byłbym wdzięczny za przemyślenia.
Nie jestem całkiem pewien, czego chcesz, ale myślę, że szukasz dekoratorów. –
@ Klasyczne: dekoratorzy nie pomagają. Dla jasności, szukam podklasy, która definiuje jako listę metody w klasie nadrzędnej, które mają zmienić konteksty przed i po wykonaniu. Metody z kolei nie musiałyby być indywidualnie definiowane w podklasie (a zatem nie byłoby miejsca dla dekoratora). –