TL;DR: Python; I have Parent, Child classes. I have an instance of Parent class, parent. Can I make a Child class instance whose super() is parent?
Somewhat specific use case (workaround available) is as follows: I'd like to make an instance of Logger class (from Python logging module), with _log method overloaded. Methods like logger.info or logger.error call this method with a level specified as either INFO or ERROR etc., I'd like to replace this one method, touch nothing else, and make it all work seamlessly.
Here's some things that don't work (well):
- I can't just inherit from
logging.Loggerinstance and overload this one method and constructor, becauseLoggerinstances tend to be created via a factory method,logging.getLogger(name). So I can't just overload the constructor of the wrapper like:
class WrappedLogger(logging.Logger):
def __init__(self, ...):
super().__init__(...)
def _log(self, ...):
and expect it to all work OK.
- I could make a wrapper class, which provides the methods I'd like to call on the resulting instance, like
.infoor.error- but then I have to manually come up with all the cases. It also doesn't work well when the_logmethod is buried a few calls down the stack - there is basically no way to guarantee that any use of the wrapped class will call my desired_logmethod - I can make a little kludge like so:
class WrappedLogger(logging.Logger):
def __init__(self, parent):
self._parent = parent
def _log(...): # overload
def __getattr__(self, method_name):
return getattr(self._parent, method_name)
now whenever I have an instance of this class, and call, say, wrapped.info(...), it will retrieve the parent method of info, call it, which will then call self._log which in turn points to my wrapped instance. But this feels very ugly.
- Similarly, I could take a regular instance of
Loggerand manually swap out the method; this is maybe a bit less "clever", and less ugly than the above, but similarly underwhelming.
This question has been asked a few times, but in slightly different contexts, where other solutions were proposed. Rather than looking for a workaround, I'm interested in whether there is a native way of constructing a child class instance with the parent instance specified.
Related questions:
- Create child class instances from parent class instance, and call parent methods from child class instance - here effectively a workaround is suggested
- Python construct child class from parent - here the parent can be created in the child's constructor