I have code like this:
class Debug(object): ... @property def ThreadAwareLogger(self): if not self.logger_instance_for_current_thread: self.logger_instance_for_current_thread=self.cloneMainLogger() return self.logger_instance_for_current_thread def cloneMainLogger(self): return logger_instance_for_current_thread class SomeOtherClass(object): def __init__(self): ... self.logger=debug.ThreadAwareLogger def otherMethod(self): ... self.logger.info("Message")
The problematic thing is the assignment
self.logger=debug.ThreadAwareLogger. I'm not sure what is gonna be content of
self.logger. I want it to be the whole getter and I want to have the getter executed everytime when I use
SomeOtherClass. But I'm affraid that in
self.logger will be stored just the result of the getter
logger_instance_for_current_thread. That means logger of the thread which was active at the time of assignment. This logger doesn't have to be the right one when I call
How to get the getter
ThreadAwareLogger executed everytime when I call
Sidenote: Why I actually need the shortcut
self.logger? When I decide to replace ThreadAwareLogger with AdvancedThreadAwareLogger I will change just one assignment instead of thousand calls of
self.logger.info("Message"). Also is None of the business of the
otherMethod to care about which logger will be used.
The assignment of getter works as described in the answer by @unutbu. But assigning of the getter causes an issue I didn't think before.
ThreadAwareLogger I actually call method
cloneMainLogger. Now the call of someOtherClass.logger ends with exception: AttributeError: 'SomeOtherClass' object has no attribute 'cloneMainLogger'.
So far I bypassed the issue with a small hack. The
SomeOtherClass actually has a
Debug instance. So I call
debug.cloneMainLogger() instead of
self.cloneMainLogger() inside of
ThreadAwareLogger. The program now works, but I consider it really dirty.
If I add line
self.comptreeLogger=Debug.ThreaAwareLogger inside of a method; e.g.
cloneMainLogger I'm getting AttributeError: 'property' object has no attribute 'debug'. Conclusion: I still don't understand the solution.
loggers = [logging.getLogger('abc'),logging.getLogger('def')]
for i in range(5):
yields output like:
Notice the changes in
def show that the
Debug.ThreadAwareLogger function is getting called each time.
One way to get the whole property would be to just make another property:
There might be other ways, too.
self.logger will refer to what is returned by the property
ThreadAwareLogger, not to the property itself.