Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting an object into a subclass in Python?

Tags:

python

Lets say I have a library function that I cannot change that produces an object of class A, and I have created a class B that inherits from A.

What is the most straightforward way of using the library function to produce an object of class B?

edit- I was asked in a comment for more detail, so here goes:

PyTables is a package that handles hierarchical datasets in python. The bit I use most is its ability to manage data that is partially on disk. It provides an 'Array' type which only comes with extended slicing, but I need to select arbitrary rows. Numpy offers this capability - you can select by providing a boolean array of the same length as the array you are selecting from. Therefore, I wanted to subclass Array to add this new functionality.

In a more abstract sense this is a problem I have considered before. The usual solution is as has already been suggested- Have a constructor for B that takes an A and additional arguments, and then pulls out the relevant bits of A to insert into B. As it seemed like a fairly basic problem, I asked to question to see if there were any standard solutions I wasn't aware of.

like image 590
saffsd Avatar asked Feb 28 '09 00:02

saffsd


People also ask

Can you create an object from a subclass?

In inheritance, subclass acquires super class properties. An important point to note is, when a subclass object is created, a separate object of a superclass object will not be created. Only a subclass object is created that has superclass variables.

Can a superclass object be treated as a subclass object?

ANS: c. Objects of a subclass can be treated like objects of their superclass.

What does it mean to subclass in Python?

The class from which a class inherits is called the parent or superclass. A class which inherits from a superclass is called a subclass, also called heir class or child class. Superclasses are sometimes called ancestors as well.

Is subclass an object?

Object is the root of a hierarchy of classes. The subclass inherits state and behavior in the form of variables and methods from its superclass. The subclass can just use the items inherited from its superclass as is, or the subclass can modify or override it.


2 Answers

This can be done if the initializer of the subclass can handle it, or you write an explicit upgrader. Here is an example:

class A(object):     def __init__(self):         self.x = 1  class B(A):     def __init__(self):         super(B, self).__init__()         self._init_B()     def _init_B(self):         self.x += 1  a = A() b = a b.__class__ = B b._init_B()  assert b.x == 2 
like image 170
ironfroggy Avatar answered Sep 25 '22 08:09

ironfroggy


Since the library function returns an A, you can't make it return a B without changing it.

One thing you can do is write a function to take the fields of the A instance and copy them over into a new B instance:

class A: # defined by the library     def __init__(self, field):         self.field = field  class B(A): # your fancy new class     def __init__(self, field, field2):         self.field = field         self.field2 = field2 # B has some fancy extra stuff  def b_from_a(a_instance, field2):     """Given an instance of A, return a new instance of B."""     return B(a_instance.field, field2)   a = A("spam") # this could be your A instance from the library b = b_from_a(a, "ham") # make a new B which has the data from a  print b.field, b.field2 # prints "spam ham" 

Edit: depending on your situation, composition instead of inheritance could be a good bet; that is your B class could just contain an instance of A instead of inheriting:

class B2: # doesn't have to inherit from A     def __init__(self, a, field2):         self._a = a # using composition instead         self.field2 = field2      @property     def field(self): # pass accesses to a         return self._a.field     # could provide setter, deleter, etc  a = A("spam") b = B2(a, "ham")  print b.field, b.field2 # prints "spam ham" 
like image 38
Kiv Avatar answered Sep 23 '22 08:09

Kiv