Python: Getting baseclass values from derived class

前端 未结 2 1420
离开以前
离开以前 2021-01-11 15:01

Hope this is clear enough:

class myParent():
    def __init__( self ):
        self.parentNumber = 5

class Child( myParent ):
    def __init__( self ):
             


        
相关标签:
2条回答
  • 2021-01-11 15:10
    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()

    You can usually manage just fine without super when you don't have multiple inheritance or other border cases, although if the base class changes, you will need to remember to change the parent class name from init (and any other method that refers to myParent explicitly).

    If your parent's __init__ takes parameters, you need to pass them on from the child's __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 dislike the repetition of customParam in all child classes, there's an alternative OO pattern called two phase construction, which 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 pattern, you don't need to repeat any of the parent's parameters, or even call the parent's __init__ in the child, but the downside is that you will need to remember to 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 here. Inheritance is about type hierarchy, and you seem to be after an ownership hierarchy (is-a versus has-a).

    I would structure your updated code like this:

    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()
    0 讨论(0)
  • 2021-01-11 15:31

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

    Also note that

    class C(object):
        x = ...
    

    is very different from

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

    The former creates a class variable, which is shared by all instances of C. The latter create an instance variable, each instance of C has it's own. (Likewise, global variables aren't bound to instances - but I assume you were talking about the above?)

    0 讨论(0)
提交回复
热议问题