Python由于最早期受C/C++语言的影响,有很多C/C++的语言设计思想,比如多重继承。其中与对象内存初始化有关的就是构造器,本主题专门讨论下Python中类的构造器:
- 子类实例化时,父类构造器的调用机制
- 父类构造器的调用方式
1. 子类实例化时,父类构造器的调用机制
当子类实例化时,其拥有的数据成员分布在子类中定义和父类中定义,其初始化分别由各自的构造器负责初始化。下面使用例子说明:
class A :
def __init__ ( self ) :
print ( "A" )
class B ( A ) :
def __init__ ( self ) :
print ( "B" )
b = B ( )
#输出如下:
B
从上面代码的输出应该得出结论:子类实例化,不会自动调用父类构造器,因为构造器也是特殊函数,其参数具有一定的复杂性,一般编译器无法自动传递参数,所以父类构造器的调用,需要开发者自己在编码中设计实现。
注意:Python函数支持像C++一样的默认参数语法特性,所以不提供函数重载(C++支持,但C++的函数调用因为歧义性,所以调用比较小心)。下面是多个构造器的例子,在调用构造器会报错,因为第二个构造器的定义覆盖了第一个:
class ClsA :
def __init__ ( self ) :
print ( "A1" )
def __init__ ( self, x ) :
print ( "A2" )
a1 = ClsA ( )
a2 = ClsA ( 20 )
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-d26e09d6d62e> in <module>()
6
7
----> 8 a1 = ClsA ( )
9 a2 = ClsA ( 20 )
TypeError: __init__() missing 1 required positional argument: 'x'
下面是一个类有多个一样函数名的函数的例子:
class MCls :
def add ( a, b ) :
return a + b
def add ( a, b, c ):
return a + b + c
m=MCls()
m.add ( 45, 55 ) #第一个add被第二个add覆盖。所以这里调用会出错
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-4e9266d7949a> in <module>()
6
7 m=MCls()
----> 8 m.add ( 45, 55 )
<ipython-input-7-4e9266d7949a> in add(a, b, c)
3 return a + b
4 def add ( a, b, c ):
----> 5 return a + b + c
6
7 m=MCls()
TypeError: unsupported operand type(s) for +: 'MCls' and 'int'
2. 在子类构造器中,调用父类构造器的方式
构造器的调用遵循函数的调用规则,就是必须的参数必须个数匹配(类型匹配是内部逻辑检测的问题,一般不会导致语法错误)
2.1. 使用父类名直接调用
这种调用方式最直观,语法规则:
父类名.init(参数列表)
下面是使用例子代码:
class A:
def __init__(self,x):
print("A")
class B(A):
def __init__(self):
print("B")
A.__init__(self,20)
b=B()
B
A
2.2. 使用super类
super是Python语言内置的类,使用super返回一个指向父类实例的对象。super的定义如下:
class super(object):
def init(self, type1=None, type2=None): # known special case of super.init
使用方式:
super(类型,self).init ( 参数列表 )
class A:
def __init__( self, x ) :
print ( "A" )
self.x = x
class B( A ) :
def __init__( self ) :
print( "B" )
super ( B, self ).__init__ ( 20 )
b=B()
B
A
注意:使用super也可以调用父类方法。
class A:
def __init__( self, x ) :
print ( "A" )
self.x = x
def methA ( self ) :
print ("method A", self.x )
class B( A ) :
def __init__( self ) :
print( "B" )
super ( B, self ).__init__ ( 20 )
def methB( self ):
super().methA ()
b=B()
b.methB()
B
A
method A 20
资源
(NONE)