G M
G M

Reputation: 22459

How to inherit _init_ from an instance of a class?

I would like to inherit all the __init__ of an instance of a class. For example if a have a class Lens and a lens "L50mm" instance of it. I would like that my camera with the "L50mm" inherit all the __init__ of the lens like this:

class Lens:
   def __init__(self,focallength,aperture):
       self.focallength=focallength
       self.aperture=aperture

L50mm=Lens(50,2.2)

class Camera:
    def __init__(self,name,sensor,lens='None'):
        self.name=name
        self.sensor=sensor
        if lens!='None':#if I have a lens mounted I want that all the __init__ is inherited e.g.:
            super(Lens).__init__()#something like this I KNOW it doesn't work
        else:#if I don't have a lens just keep 'None'
            self.lens=lens

mycamera=Camera('DSCF828','CCD',L50mm)
>>TypeError: must be type, not classobj

Of course I know that I can put self.lens=lens in the Camera __init__ method but I was wondering if there is a more direct way to inherit all the properties.

The main goal is to access directly all the methods:

mycamera.focallength
mycamera.aperture

instead of:

mycamera.lens.aperture
mycamera.lens.focallength

Instead self.lens = Lens() as suggested in the comment doesn't make any sense for me beacause I would have to pass all the parameters again, so please read carefully the question.

Upvotes: 0

Views: 93

Answers (3)

loutre
loutre

Reputation: 894

My opinion is that you're not using POO the right way. If you really want to do that, try something like:

for attr in dir(lens):
    setattr(self, attr, getattr(attr, lens))

e.g:

class Lens:
    def __init__(self, a, b):
        self.a, self.b = a, b

class Camera:
    def __init__(self, lens):
         for attr in dir(lens):
             setattr(self, attr, getattr(attr, lens))

lens = Lens(12, 13)
cam = Camera(lens)
cam.a

Read the answer's comments, you'll understand how dirty it is :)

Upvotes: 0

Håken Lid
Håken Lid

Reputation: 23064

This can be done using composition instead of inheritance. This assumes that you know which properties you need from Lens.

class Camera:
    def __init__(self,name,sensor,lens=None):
        self.name=name
        self.sensor=sensor
        if lens is not None:
            self.focallength = lens.focallength
            self.aperture = lens.aperture

Upvotes: 1

skyking
skyking

Reputation: 14359

I wonder if you really want to do inheritance actually, at least not in the traditional object oriented sense. Simply because the camera is not a lens, so theres no proper super/sub type relation between them.

What you might want is to wrap the attributes of lens in the Camera. I'm not saying it's a good idea, but it is sure possible. What you can do is to override the __getattr__:

 class Camera(object):
      def __getattr__(self, key):
            return getattr(self.lens, key)

      def __init__(self,name,sensor,lens=None):
             self.name=name
             self.sensor = sensor
             self.lens = lens

this means that if you have a camera object cam and tries to access a member of it, if that fails in the normal way it tries to use getattr(self.lens, key) instead. For example cam.focallength fails in the traditional sense (since there's no focallength in camera, but instead it will go on an try to effectively translate that into cam.lens.focallength instead.

Upvotes: 3

Related Questions