2

While I managed to construct a manageable answer to my question:

class A(object):
    def __init__(self, B, *args, **kwargs):
        ''' Modifies input class B, rendering it a super class of class A'''
        _parent = {}
        method_list = [func for func in dir(self) if callable(getattr(self, func))]
        for att in B.__dir__():
            _parent[att] = B.__getattribute__(att)
            if att not in method_list:
                try:
                    self.__setattr__(att, B.__getattribute__(
                        att))

                except:
                    pass
        B.__init__(self, *args, **kwargs)
        self.__parent__ = _parent
        #add self variables here

    def func(self):
        #modify inherited func here
        self.__parent__['func']()
        #modify inherited func here

I do not know if it always works and I would like to know if someone else has a better solution to this (rather trivial for other languages) question. Also, this solution is only applicable in Python3 and above (otherwise inspect module is needed for the replacement of the callable part)

Vasilis Lemonidis
  • 636
  • 1
  • 7
  • 25
  • Python 2.7 supports `callable` as well. Also when modifying class objects, you may consider using metaclasses – Chen A. Oct 10 '17 at 10:24
  • I did not test it myself. This comment was based on [this](https://stackoverflow.com/questions/1911281/how-do-i-get-list-of-methods-in-a-python-class) . If it is applicable, then my research is probably wrong.. – Vasilis Lemonidis Oct 10 '17 at 10:27
  • I would use `inspect` module. You can do `inspect(obj, inspect.ismethod)` which seems more readable imo – Chen A. Oct 10 '17 at 10:28
  • What are you trying to do exactly ??? – bruno desthuilliers Oct 10 '17 at 10:31
  • I edited the class doc for a better explanation of what I want to do. – Vasilis Lemonidis Oct 10 '17 at 10:40
  • Assuming you don't want to, for some reason, use the common inheritance mechanism (or metaclass) you need to decide if you want to change the class (by adding new methods or base class after its definition), or just an instantiation. Although I can see some cases where either might be useful, I don't think it to be a good practice. In any case check [this](https://stackoverflow.com/questions/972/adding-a-method-to-an-existing-object-instance) and [this](https://stackoverflow.com/questions/9539052/how-to-dynamically-change-base-class-of-instances-at-runtime) questions for more. – armatita Oct 10 '17 at 11:07
  • And by the way changing objects at run time is not trivial for the great majority of languages. Its actually quite an exclusive club. That gets me to think you might actually be a Javascript developer and what you are looking for is actually [Prototyping](https://en.wikipedia.org/wiki/Prototype-based_programming). There's a [lib in Github](https://github.com/airportyh/prototype.py/blob/master/doc.py) to facilitate things for you if that is the case. – armatita Oct 10 '17 at 11:23
  • You are right, but I did not say anything about changing them in runtime in the first place. C++ does it in compilation for example, if I am not mistaken. Either way, there is a multitude of reasons why I would try to do this. For example, I would like to modify the fit method of all sklearn classifiers programmatically, or add the same logging mechanism to any arbitrary class, without having to super class each one. – Vasilis Lemonidis Oct 10 '17 at 11:34
  • 1
    Yeah, but it makes a difference when you say "go up" to a car or to a helicopter. Python has very powerful meta features meaning that your use of the word "arbitrary" in the title is basically being interpreted as do this wherever, whenever. Those two particular operations can be done with metaclasses. You can either inherit the classifiers and build your own object (and programmatically change the fit method), or add stuff to the original classes (search a bit for class patching in python). – armatita Oct 10 '17 at 12:10

0 Answers0