python类变量和实例变量在继承中如何取值

类变量:可在类的所有实例之间共享的变量
实例类对象:类的实例是调用类对象来创建的。如:par = Parent(),par就是类Parent的一个实例类对象。
实例变量:同一个类对象可以创建多个实例类对象,类定义中有self标志的变量就是实例变量

一、python类变量在继承中取值方式如下:

1,如果该变量在该类中有定义,则使用该值。
2,如果没有,将搜索父类,多继承时采用C3方法,一般不存在交叉的类都是从左到右顺序搜索。搜索过程中如果前面父类的值被重新赋值,则类变量值将改变成该值
关于C3方法详情请看http://www.nanerbang.com/article/40/
如果不想搞懂,直接调用 类名.mro()打印出来看一下搜索顺序

二、python实例变量在继承中取值方式如下:

1,搜索方式和类变量一样,先找自己,在找父类,多继承也是使用C3,一般不存在交叉的类时按照从左到右顺序搜索
2,实例变量只会继承最开始的初始值,即使父类中的实例变量值被重新赋值,子类的值也不会跟着改变,仍会选择最开始的初始值。

三、举例证明

运行环境:python3.6
例一,继承关系Children1继承自Parent,Children2也继承自Parent。

class Parent(object):
    x = 1  # 类变量
    def __init__(self):
        self.y = 1  # 实例变量
class Children1(Parent):
    pass
class Children2(Parent):
    pass
par = Parent()  # 具体的类实例对象
child1 = Children1()  # 具体的类实例对象
child2 = Children2()  # 具体的类实例对象
print('-------------------------------------')
print('Parent.x=', Parent.x, ',Children1.x=', Children1.x, ',Children2.x=', Children2.x)
print('par.y=', par.y, ',child1.y=', child1.y, ',child2.y=', child2.y)

print('-------------------------------------')
Children1.x = 2
child1.y = 2
print('Parent.x=', Parent.x, ',Children1.x=', Children1.x, ',Children2.x=', Children2.x)
print('par.y=', par.y, ',child1.y=', child1.y, ',child2.y=', child2.y)

print('-------------------------------------')
Parent.x = 3
par.y = 3
print('Parent=', Parent.x, ',Children1=', Children1.x, ',Children2=', Children2.x)
print('par.y=', par.y, ',child1.y=', child1.y, ',child2.y=', child2.y)

print('-------------------------------------')
Children2.x = 4
child2.y = 4
print('Parent=', Parent.x, ',Children1=', Children1.x, ',Children2=', Children2.x)
print('par.y=', par.y, ',child1.y=', child1.y, ',child2.y=', child2.y)

输出结果:

-------------------------------------
Parent.x= 1 ,Children1.x= 1 ,Children2.x= 1
par.y= 1 ,child1.y= 1 ,child2.y= 1
-------------------------------------
Parent.x= 1 ,Children1.x= 2 ,Children2.x= 1
par.y= 1 ,child1.y= 2 ,child2.y= 1
-------------------------------------
Parent.x= 3 ,Children1.x= 2 ,Children2.x= 3
par.y= 3 ,child1.y= 2 ,child2.y= 1
-------------------------------------
Parent.x= 3 ,Children1.x= 2 ,Children2.x= 4
par.y= 3 ,child1.y= 2 ,child2.y= 4

总结:
1,对于类变量x,最开始Children1和Children2都没有赋值x,所以都等于1。当Children1赋值2之后值就变了,但Children2还是之前的1,当父类修改为3后,由于Children2一直没有赋值,所以等于修改后的父类的x值3,直到Children2自己赋值才是4。
2,对于实例变量y,最开始child1和child2都没有对y赋值,所以都等于1。当child1变成2之后就变成2,但child2还是之前的1,即使父类实例par改变y的值为3,child2还是为1。直到child2自己赋值为4才改变。

例二,GrandChildren继承自Children,Children继承自Parent

class Parent(object):
    x = 1
    def __init__(self):
        self.y = 1
class Children(Parent):
    pass
class GrandChildren(Children):
    pass
par = Parent()
child = Children()
grand = GrandChildren()
print('-------------------------------------')
print('Parent.x=', Parent.x, ',Children.x=', Children.x, ',GrandChildren.x=', GrandChildren.x)
print('par.y=', par.y, ',child.y=', child.y, ',grand.y=', grand.y)

print('-------------------------------------')
Children.x = 2
child.y = 2
print('Parent.x=', Parent.x, ',Children.x=', Children.x, ',GrandChildren.x=', GrandChildren.x)
print('par.y=', par.y, ',child.y=', child.y, ',grand.y=', grand.y)

print('-------------------------------------')
Parent.x = 3
par.y = 3
print('Parent.x=', Parent.x, ',Children.x=', Children.x, ',GrandChildren.x=', GrandChildren.x)
print('par.y=', par.y, ',child.y=', child.y, ',grand.y=', grand.y)

print('-------------------------------------')
GrandChildren.x = 4
grand.y = 4
print('Parent.x=', Parent.x, ',Children.x=', Children.x, ',GrandChildren.x=', GrandChildren.x)
print('par.y=', par.y, ',child.y=', child.y, ',grand.y=', grand.y)

输出结果:

-------------------------------------
Parent.x= 1 ,Children.x= 1 ,GrandChildren.x= 1
par.y= 1 ,child.y= 1 ,grand.y= 1
-------------------------------------
Parent.x= 1 ,Children.x= 2 ,GrandChildren.x= 2
par.y= 1 ,child.y= 2 ,grand.y= 1
-------------------------------------
Parent.x= 3 ,Children.x= 2 ,GrandChildren.x= 2
par.y= 3 ,child.y= 2 ,grand.y= 1
-------------------------------------
Parent.x= 3 ,Children.x= 2 ,GrandChildren.x= 4
par.y= 3 ,child.y= 2 ,grand.y= 4

总结:
1,对于类变量x,最开始Children和GrandChildren都没有赋值x,所以都等于1。当Children赋值2之后值就变了,GrandChildren也跟着变,当父类修改后,由于Children2在之前赋值为2,所以即使修改了父类的x,但也不会访问到他。GrandChildren自己赋值为3就会变成4,不影响Parent和GrandChildren。
2,对于实例变量y,最开始child和grand都没有对y赋值,所以都等于1。当child变成2之后就变成2,但grand还是最开始的初值1,即使父类实例par改变y的值为3,grand还是1。直到grand自己赋值为4才改变。

例三、GrandChildren继承自Children1和Children2,Children1继承自Parent,Children2继承自Parent

class Parent(object):
    x = 1  # 类变量
    def __init__(self):
        self.y = 1  # 实例变量
class Children1(Parent):
    pass
class Children2(Parent):
    def __init__(self):
        Parent.__init__(self)
        self.y = 90
class GrandChildren(Children1, Children2):
    pass
par = Parent()
child1 = Children1()
child2 = Children2()
grand = GrandChildren()
print('-------------------------------------')
print('Parent=', Parent.x, ',Children1.x=', Children1.x, ',Children2.x=', Children2.x, ',GrandChildren.x=',
      GrandChildren.x)
print('par.y=', par.y, ',child1.y=', child1.y, ',child2.y=', child2.y, ',grand.y=', grand.y)

print('-------------------------------------')
Children1.x = 2
child1.y = 2
print('Parent=', Parent.x, ',Children1.x=', Children1.x, ',Children2.x=', Children2.x, ',GrandChildren.x=',
      GrandChildren.x)
print('par.y=', par.y, ',child1.y=', child1.y, ',child2.y=', child2.y, ',grand.y=', grand.y)

print('-------------------------------------')
Children2.x = 3
child2.y = 3
print('Parent=', Parent.x, ',Children1.x=', Children1.x, ',Children2.x=', Children2.x, ',GrandChildren.x=',
      GrandChildren.x)
print('par.y=', par.y, ',child1.y=', child1.y, ',child2.y=', child2.y, ',grand.y=', grand.y)

print('-------------------------------------')
GrandChildren.x = 4
grand.y = 4
print('Parent=', Parent.x, ',Children1.x=', Children1.x, ',Children2.x=', Children2.x, ',GrandChildren.x=',
      GrandChildren.x)
print('par.y=', par.y, ',child1.y=', child1.y, ',child2.y=', child2.y, ',grand.y=', grand.y)

输出结果

扫描二维码关注公众号,回复: 2682782 查看本文章
-------------------------------------
Parent= 1 ,Children1.x= 1 ,Children2.x= 1 ,GrandChildren.x= 1
par.y= 1 ,child1.y= 1 ,child2.y= 90 ,grand.y= 90
-------------------------------------
Parent= 1 ,Children1.x= 2 ,Children2.x= 1 ,GrandChildren.x= 2
par.y= 1 ,child1.y= 2 ,child2.y= 90 ,grand.y= 90
-------------------------------------
Parent= 1 ,Children1.x= 2 ,Children2.x= 3 ,GrandChildren.x= 2
par.y= 1 ,child1.y= 2 ,child2.y= 3 ,grand.y= 90
-------------------------------------
Parent= 1 ,Children1.x= 2 ,Children2.x= 3 ,GrandChildren.x= 4
par.y= 1 ,child1.y= 2 ,child2.y= 3 ,grand.y= 4

总结:
1,对于类变量x,最开始Children1、Children2和GrandChildren都没有赋值x,所以都等于1。当Children1赋值2之后值就变了,但Children2还是之前的1,由于GrandChildren先继承Children1,所以等于修改后的Children1的x值2,即使Children2修改值为3,GrandChildren也是取值于Children1,直到GrandChildren自己赋值才是4。
2,对于实例变量y,最开始child1没有对y赋值所有搜索到父类值为1,但child2有初始值90,所以为90,grand没有初始化,先搜索child1,由于没有初始化,继续搜索child2,此时有初始化所以grand初始值为90。当child1赋值2之后就变成2,child2还是之前的90,grand也是90。即使child1和child2值都重新赋初值后,grand还是最开始的90。直到grand自己赋值为4才改变。

猜你喜欢

转载自blog.csdn.net/u014734886/article/details/80691402