Python: getting base class values ​​from a derived class

Hope this is clear enough:

class myParent(): def __init__( self ): self.parentNumber = 5 class Child( myParent ): def __init__( self ): self.childNumber = 4 def multiplyNumbers( self ): print myParent.parentNumber * self.childNumber p = Child() p.multiplyNumbers() 

I want to set the parent number separately, and then reach that number through the child class and in this case use it for some multiplication.

I am new to OOP, so any generic inheritance pointers are also welcome!

Additional Information: I am developing a project management solution for vfx-based projects and playing with classes and inheritance to see how they can help me.

I now have a class, Project, and a Shot derived class. Shot has a self.length variable with the length of a particular frame. He also got the getLengthInSeconds () method, which uses self.length along with Project.fps to determine the length in seconds. The project has a setFps () method in which fps is set after the class is instantiated.

I'm kind of used to variables that have a prefix. and haven’t experimented much with classes using more “global” variables without an “I.” If I do everything global, I don’t know, I can use Project.fps without any hassle, but I get a warning about “bad programming practice” in my unskilled condition. Perhaps there is a better, neater way?

Edit:

After some reading, super () seems like something dangerous, and a little more than I need, I think. I basically have single inheritance classes and am not even sure how to use dialog hierarchies. Is there a safer way to access superclass variables and methods that do not include super ()?

Edit:

Okay, let's see if this makes sense or I think it's all wrong.

I view classes and inheritance as groups and children. A child knows its parent and all its meanings. A child knows to another parent what parents value. What I'm trying to accomplish is that all the snapshots created are part of the project. And right now I'm creating Shot () instances from the Project () class, adding instances to the list of snapshots that are then supported in the Project () instance.

i.e.

 class myParent( object ): def __init__( self ): self.parent_id = '' self.children = [] def createChild( self, name ): self.children.append( myChild( name ) ) def getChildren( self ): return self.children def setParentId( self, id ): self.parentId = id class myChild( myParent ): def __init__( self, id ): super(myChild, self).__init__() self.id = id def getParentId( self ): return self.parent_id p = myParent() p.setParentId( 'parent01' ) p.createChild( 'child01' ) print p.getChildren()[0].getParentId() 

I can look at the erroneous steps in the logic here, but there is no real way. It seems that every child gets a new instance of the parent in a way where parent_id is always an empty string.

+7
source share
2 answers
 class myParent( object ): def __init__( self ): self.parentNumber = 5 class Child( myParent ): def __init__( self ): myParent.__init__( self ) self.childNumber = 4 def multiplyNumbers( self ): print self.parentNumber * self.childNumber p = Child() p.multiplyNumbers() 

Usually, you can easily manage without super if you don't have multiple inheritance or other cases with borders, although if the base class changes, you will need to remember the name of the parent class with init (and any other method that explicitly references myParent).

If your parent __init__ accepts the parameters, you need to pass them from the child __init__ .

 class myParent( object ): def __init__( self, customParam ): self.parentNumber = 5 self.customParam = customParam class Child( myParent ): def __init__( self, customParam ): myParent.__init__( self, customParam ) self.childNumber = 4 

If you don't like repeating customParam in all child classes, there is an alternative OO pattern called a two-phase construct that works like this:

 class myParent( object ): def customInit( self, customParam ): self.parentNumber = 5 self.customParam = customParam class Child( myParent ): def __init__( self, customParam ): self.childNumber = 4 p = Child() p.customInit(10) p.multiplyNumbers() 

In this template, you do not need to repeat any parent parameters or even call the parent __init__ in the child element, but the disadvantage is that you will need to remember that you always call the secondary constructor when creating objects or your object will be left partially uninitialized.

UPDATE (to answer the updated question):

You seem to be mixing two unrelated concepts of parenthood. Inheritance is a type hierarchy, and you seem to be after a property hierarchy (is-a versus has-a).

I would structure your updated code as follows:

 class myParent( object ): def __init__( self, parentId ): self.id = parentId self.children = [] def createChild( self, name ): self.children.append( myChild( name, self ) ) def getChildren( self ): return self.children class myChild( object ): def __init__( self, childId, parent ): self.id = childId self.parent = parent def getParentId( self ): return self.parent.id p = myParent( 'parent01' ) p.createChild( 'child01' ) print p.getChildren()[0].getParentId() 
+5
source

You just need to tell Child to start initialization from myParent . After that, the current instance ( self ) has all the attributes of the instance that has the instance myParent ( "is" ) so you can use self.parentNumber . You do this by putting super(Child, self).__init__() in Child.__init__ (ideally on the very first line) - myParent.__init__(self) will work, but it may be wrong (in a subtle way) when the base the class changes or in the case of multiple inheritance. You can drop all arguments to super if you are using Python 3.

Also note that

 class C(object): x = ... 

very different from

 class C(object): def __init__(self): self.x = ... 

The first creates a class variable that is shared by all instances of C The latter create an instance variable, each instance of C has its own. (Likewise, global variables are not instance bound, but I assume you talked about this?)

+5
source

All Articles