I have a setup like the following
class decorator:
def __init__(self, fn):
self.fn = fn
@staticmethod
def wrap(fn):
return decorator(fn)
def __call__(self):
print(f"decorator {self} function called")
class A:
@decorator.wrap
def foo(self):
print(f"Object {self} called")
def __init__(self):
self.boo = 'Boo'
How do I from the decorator object access boo
variable?
@S.B's solution works but is not thread-safe since multiple instances of A
may be calling the foo
method at about the same time in different threads, overriding the decorator object's instance
attribute before a call to the __call__
method originated from another instance is made.
A thread-safe approach would be to return a wrapper function from the __get__
method with the instance available through closure:
class decorator:
def __init__(self, fn):
self.fn = fn
def __get__(self, instance, owner=None):
def wrapper(*args, **kwargs):
print(f'decorator {self} function called; boo = {instance.boo}')
return self.fn(instance, *args, **kwargs)
return wrapper
class A:
@decorator
def foo(self):
print(f"Object {self} called")
def __init__(self):
self.boo = 'Boo'
A().foo()
This outputs:
decorator <__main__.decorator object at 0x7f6ef3316c10> function called; boo = Boo
Object <__main__.A object at 0x7f6ef3339580> called
Demo: Try it online!