Neon Physics
Neon Physics

Reputation: 3477

Python: Inheriting methods of a parent class without being a child of the class

I can't seem to find information regarding what I'm trying to do, so I'm afraid the answer is "you can't do it" or "that's bad practice." But, here it goes:

Given the following:

Class A(object):
  def __init__(self):
    pass
  def methoda(self):
    return 1

Class C(object):
  def __init__(self):
    pass
  def methodc(self):
    return 2

import A, C
Class B(object):
  def __init__(self, classC):
    A.__init__(self)
      if classC:
         C.__init__(self)
  def methodb(self):
    return 2

Obviously, running:

b = A() 
b.methoda()

Is going to crash with an error:

Unbound method __init()___ must be called with A class as first argument (got B instance instead)

However, I am basically looking for a way to make this work. My motivation:

There are classes (maybe in the future) that will duplicate a certain group of methods (say some fancy conversions). In an effort to reduce code, I'd like for the future classes to inherit the methods; but for legacy reasons, I don't want B to inherit C.

Upvotes: 1

Views: 56

Answers (2)

Neon Physics
Neon Physics

Reputation: 3477

I ended up just inheriting multiple classes. It's not exactly the way I wanted it done, but it's cleaner and easier for the IDE to follow

Class A(object):
  def __init__(self):
    super(A, self).__init__()
    pass
  def methoda(self):
    return 1

Class C(object):
  def __init__(self):
    super(C, self).__init__()
  def _C_init(self):
    # some init stuff
    pass
  def methodc(self):
    return 1

Class B(A, C):
  def __init__(self, use_C):
    super(B, self).__init__()
    if use_C:
      self._C_init()
  def methodb(self):
    return 2

Upvotes: 0

ShadowRanger
ShadowRanger

Reputation: 155333

A couple solutions:

Don't use special methods directly:

class A(object):
    def __init__(self):
        self._init(self)
    @staticmethod
    def _init(self):
        ...actual initialization code here...
    def methoda(self):
        return 1

class C(object):
    def __init__(self):
        self._init(self)
    @staticmethod
    def _init(self):
        ...actual initialization code here...
    def methodc(self):
        return 2

import A, C
class B(object):
    def __init__(self, classC):
        A._init(self)
        if classC:
            C._init(self)
    def methodb(self):
        return 2

Or silly hacks involving copying from initialized objects:

import A, C
class B(object):
    def __init__(self, classC):
        vars(self).update(vars(A()))
        if classC:
            vars(self).update(vars(C()))
    def methodb(self):
        return 2

Note that none of these solutions will give access to methods from A or C on instances of B. That's just ugly. If you really need inheritance, use inheritance, don't do terrible things trying to simulate it poorly.

Upvotes: 1

Related Questions