希望这很清楚:
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总是一个空字符串。
答案 0 :(得分:6)
您只需告诉Child
从myParent
运行初始化。之后,当前实例(self
)具有 myParent
的实例所具有的所有实例属性("is a"),因此您可以使用{{1 }}。你可以将self.parentNumber
放入super(Child, self).__init__()
(理想情况下,在第一行) - Child.__init__
可以正常工作,但是当基类更改时,它可能是错误的(以微妙的方式)在多重继承的情况下。如果您使用的是Python 3,则可以将所有参数都删除到myParent.__init__(self)
。
另请注意
super
与
非常不同class C(object):
x = ...
前者创建一个类变量,由class C(object):
def __init__(self):
self.x = ...
的所有实例共享。后者创建一个实例变量,C
的每个实例都有自己的实例。 (同样,全局变量不会绑定到实例 - 但我假设您正在讨论上述内容?)
答案 1 :(得分:5)
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()