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.Logger
instance and overload this one method and constructor, becauseLogger
instances 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
.info
or.error
- but then I have to manually come up with all the cases. It also doesn't work well when the_log
method 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_log
method - 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
Logger
and 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