簡體   English   中英

Python:從派生類中獲取基類值

[英]Python: Getting baseclass values from derived class

希望這很清楚:

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

我希望單獨設置parentNumber,然后通過子類達到該數字,在這種情況下使用它進行一些乘法。

我是OOP領域的新手,所以歡迎任何關於繼承的一般指針!

更多信息:我正在為基於vfx的項目設計項目管理解決方案,並且正在玩類和繼承,以了解它們如何能夠幫助我。

現在,我已經獲得了頂級類,Project和派生類Shot。 Shot具有self.length變量,具有特定鏡頭的長度。 它還有一個getLengthInSeconds()方法,它使用self.length和Project.fps來確定以秒為單位的長度。 Project有一個setFps()方法,其中在創建類的實例后設置fps。

我習慣於以變量為前綴的變量。 並且沒有對使用沒有自我的更“全局”變量的類進行過多嘗試。 如果我把一切都變得全球化,沒有自我,我可以毫不費力地使用Project.fps,但是我的脖子上有一個“糟糕的編程習慣”警告。 也許有更好,更整潔的方式?

編輯:

經過一番閱讀,super()似乎有點危險,比我想象的要多一些。 我主要有單繼承類,甚至不確定如何使用鑽石層次結構。是否有更安全的方法來訪問超類變量和不包含super()的方法?

編輯:

好吧,看看這是否有意義,或者我是否認為這一切都是錯的。

我正在看班級和繼承作為團體和孩子。 一個孩子知道它的父母及其所有的價值觀。 一個孩子對另一個父母知道父母的價值觀。 我想要完成的是將所有鏡頭都創建為項目的一部分。 現在,我正在從Project()類中創建Shot()實例,將實例添加到鏡頭列表中,然后在Project()實例中維護。

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

我可以在這里看到邏輯中的錯誤步驟,但沒有真正的解決方法..似乎每個孩子都以這種方式獲取父實例,其中parent_id總是一個空字符串。

您只需要告訴ChildmyParent運行初始化。 之后,當前實例( self具有 myParent的實例所具有的所有實例屬性( “是a” ),因此您可以使用self.parentNumber 你可以通過將super(Child, self).__init__()放入Child.__init__ super(Child, self).__init__()理想情況下,在第一行) - myParent.__init__(self)可以工作,但是它可能是錯誤的(以微妙的方式)基類更改或多重繼承的情況。 如果您使用的是Python 3,則可以將所有參數都刪除到super

另請注意

class C(object):
    x = ...

與...非常不同

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

前者創建一個類變量,由C的所有實例共享。 后者創建一個實例變量, C每個實例都有自己的實例。 (同樣,全局變量不綁定到實例 - 但我假設你在討論上面的內容?)

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

當你沒有多重繼承或其他邊界情況時,你通常可以在沒有super情況下管理得很好,盡管如果基類發生了變化,你需要記住從init (以及引用myParent的任何其他方法)更改父類名明確)。

如果你父母的__init__需要參數,你需要從孩子的__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

如果您不喜歡在所有子類中重復使用customParam,那么可以使用另一種稱為兩階段構造的OO模式,其工作方式如下:

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

在這種模式中,您不需要重復父項的任何參數,甚至不需要在子項中調用父項的__init__ ,但缺點是您需要記住在創建對象或對象時始終調用輔助構造函數將部分未初始化。

更新(回答更新的問題):

你似乎在這里混合了兩個不相關的父母身份概念。 繼承是關於類型層次結構的,您似乎是在所有權層次結構之后(is-a與has-a)。

我會像這樣構建你更新的代碼:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM