I have some classes that look something like this:
class Foo:
bar = None
@baz(frob=bar)
def oof():
pass
class Rab(Foo):
bar = 'zab'
I don't have control over the @baz
decorator and I need to to use the class attribute bar
of the new class Rab
. But calling Rab.oof()
uses the bar=None
of the base class.
So here is a kind of weird/interesting approach where you only need to modify Foo
, the idea here is that a new decorator is created that delays the baz
decoration until the function is first called with some caching based on the class name so that it only happens once.
Note that this also includes a dummy implementation for baz
which just prints the frob
argument that was provided, but this approach should work fine without needing to modify baz
:
def baz(frob):
def deco(func):
def wrapped(*args, **kwargs):
print('frob:', frob)
return func(*args, **kwargs)
return wrapped
return deco
def newdeco(func):
def wrapped(self, *args, **kwargs):
if not hasattr(wrapped, 'cache'):
wrapped.cache = {}
cls = self.__class__.__name__
if cls not in wrapped.cache:
wrapped.cache[cls] = baz(frob=getattr(self.__class__, 'bar'))(func)
wrapped.cache[cls](self, *args, **kwargs)
return wrapped
class Foo:
bar = None
@newdeco
def oof(self):
pass
class Rab(Foo):
bar = 'zab'
f = Foo()
f.oof()
r = Rab()
r.oof()
I also had to add a self
argument to oof
based on the assumption that oof
is a method, if baz
is also converting the function to a staticmethod I'm not sure this approach will work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With