0

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.

8
  • 3
    You're not using using super the right way. super is used to call a method of a superclass. Maybe here you just want to create a new instance of a lens if it is None ? In that case you just want to replace the super(Lens).__init__() by self.lens = Lens() Commented Mar 11, 2016 at 10:07
  • 1
    What you're doing is is that a camera not only has a lens, but camera also is-a lens, now that does not make any sense. Commented Mar 11, 2016 at 10:10
  • @AnttiHaapala when I consider my object as a whole ofcourse this is only an exaple.... Commented Mar 11, 2016 at 10:19
  • @loutre I have alreday written that at the end of my question I don't want to access the properties with Camera.Lens.property for this reason I have written this question... Commented Mar 11, 2016 at 10:20
  • @loutre I can't do that beacuse I would have to put all the paramter again.... Commented Mar 11, 2016 at 10:27

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Will this work? Shouldn't you use a try-except block and only try getattr on lens when the initial one raises an AttribueError?
@HåkenLid I hope so - the __getattr__ method does not get called unless an attribute lookup in the usual places failed.
1

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

Comments

0

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 :)

2 Comments

Warning: dir() returns many special names, including __class__!
You should probably do something to avoid changing the attributes on Camera that already have a value.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.