Python继承时类变量分析及图解

最近使用Python开发项目时遇到了一些类变量的问题,所以抽空做了一下验证,在此做个记录和分享,如理解有误,请批评指正,谢谢。

写作思路:本文会先给出自己得出的结论,然后对逐个对结论进行验证,这样方便大家理解。
图解部分是为了大家理解方便,自己通过打印变量的地址得出,有根据,但实际是否和我猜想一致,需后续再深入探究。

结论:

  1. 子类会继承父类的所有类变量
  2. 子类若没有重新定义父类的类变量,则默认使用父类的类变量,且随父类类变量的变化而变化。
  3. 子类若重新定义了部分父类的类变量,则重新定义的部分不会随着父类类变量的变化而变化。
  4. 子类对类变量重新赋值后,重新赋值的类变量不再受父类类变量的变化而变化。
  5. 子类修改类变量的值对父类没有影响

结论1

子类会继承父类的所有类变量

class Father():
    name = "老爸"
    role = "老爸是家里的顶梁柱"

class Son(Father):
    pass

if __name__ == '__main__':
    print("儿子的 name : {} 儿子的角色 :{}".format(Son.name,Son.role))
    pass

输出:
儿子的 name : 老爸 儿子的角色 :老爸是家里的顶梁柱

图解:
在这里插入图片描述
从上边例子中可以看出,子类虽然没有定义 name 和 role ,但是可以获取到并且显示的是父类的name 和 role。

结论2

子类若没有重新定义父类的类变量,则默认使用父类的类变量,且随父类类变量的变化而变化。

class Father():
    name = "老爸"
    role = "老爸是家里的顶梁柱"

class Son(Father):
    pass

if __name__ == '__main__':
    print("儿子的 name : {} 儿子的角色 :{}".format(Son.name,Son.role))
    father = Father()
    son1 = Son()
    print("father name : {} father 的角色 :{}".format(father.name, father.role))
    print("son1 name : {} son1 的角色 :{}".format(son1.name, son1.role))
    Father.name = "亲爱的老爸"
    print("----------------------add for 结论2-------------------")
    print("father name : {} father 的角色 :{}".format(father.name, father.role))
    print("son1 name : {} son1 的角色 :{}".format(son1.name, son1.role))
    print("----------------------add for 结论2-------------------")
    pass

输出:
儿子的 name : 老爸 儿子的角色 :老爸是家里的顶梁柱
father name : 老爸 father 的角色 :老爸是家里的顶梁柱
son1 name : 老爸 son1 的角色 :老爸是家里的顶梁柱
------------------------------add for 结论2------------------------------
father name : 亲爱的老爸 father 的角色 :老爸是家里的顶梁柱
son1 name : 亲爱的老爸 son1 的角色 :老爸是家里的顶梁柱
------------------------------add for 结论2------------------------------

图解:
在这里插入图片描述

在这个例子中,子类中我们没有重新定义父类的类变量,我们可以发现我们修改了父类的类变量name的值,子类的name值也发生了变化。

结论3

子类若重新定义了部分父类的类变量,则重新定义的部分不会随着父类类变量的变化而变化。

class Father():
    name = "老爸"
    role = "老爸是家里的顶梁柱"

class Son(Father):
    # add for 结论 3
    name = "儿子"
    # add for 结论 3
    pass

if __name__ == '__main__':
    print("儿子的 name : {} 儿子的角色 :{}".format(Son.name,Son.role))
    father = Father()
    son1 = Son()
    print("father name : {} father 的角色 :{}".format(father.name, father.role))
    print("son1 name : {} son1 的角色 :{}".format(son1.name, son1.role))
    print("------------- add for 结论 3 ------------")
    Father.name = "亲爱的老爸"
    Father.role = "父亲也是最严厉的那个人"
    print("------------- add for 结论 3 ------------")
    print("father name : {} father 的角色 :{}".format(father.name, father.role))
    print("son1 name : {} son1 的角色 :{}".format(son1.name, son1.role))
    pass

输出:
儿子的 name : 儿子 儿子的角色 :老爸是家里的顶梁柱
father name : 老爸 father 的角色 :老爸是家里的顶梁柱
son1 name : 儿子 son1 的角色 :老爸是家里的顶梁柱
------------- add for 结论 3 ------------
------------- add for 结论 3 ------------
father name : 亲爱的老爸 father 的角色 :父亲也是最严厉的那个人
son1 name : 儿子 son1 的角色 :父亲也是最严厉的那个人

图解:
在这里插入图片描述

在这个例子中,子类重新定义了 name 字段,父类修改了name 和 role 字段后,子类的name字段并没有随之修改,而未重新定义的role字段与父类role保持一致。

结论4

子类对类变量重新赋值后,重新赋值的类变量不再因父类类变量的变化而变化。
结论 3 中的例子已经可以说明该问题,在此单独列出来是因为修改子类类变量的方法有多种,觉得有必要写一下。

第一种:在书写子类的时候进行定义并赋值
class Father():
    name = "老爸"
    role = "老爸是家里的顶梁柱"

class Son(Father):
    # 第一种
    name = "儿子"
    # 第一种

第二种:使用子类类名进行重新赋值
class Father():
    name = "老爸"
    role = "老爸是家里的顶梁柱"

class Son(Father):
    pass

if __name__ == '__main__':
	# 第二种
    Son.name = "儿子"
    Son.role = "儿子是未来的希望"
    # 第二种

第三种:使用类方法进行修改
class Father():
    name = "老爸"
    role = "老爸是家里的顶梁柱"

class Son(Father):
    pass
	
	#----------------------  类方法写法 --------------------------
    @classmethod
    def reset_name(cls,name):
        cls.name = name
    @classmethod
    def reset_role(cls,role):
        cls.role = role
	#----------------------  类方法写法 --------------------------
	
if __name__ == '__main__':
     # 第三种
    Son.reset_name("儿子")
    Son.reset_role("儿子是未来的希望")
    # 第三种

结论5

子类修改类变量的值对父类没有影响

class Father():
    name = "老爸"
    role = "老爸是家里的顶梁柱"

class Son(Father):
    pass

if __name__ == '__main__':
    father = Father()
    son1 = Son()
    print("father name : {} father 的角色 :{}".format(father.name, father.role))
    print("son1 name : {} son1 的角色 :{}".format(son1.name, son1.role))
    Son.name = "儿子"
    Son.role = "儿子是未来的希望"
    print("father name : {} father 的角色 :{}".format(father.name, father.role))
    print("son1 name : {} son1 的角色 :{}".format(son1.name, son1.role))
    pass

输出:
father name : 老爸 father 的角色 :老爸是家里的顶梁柱
son1 name : 老爸 son1 的角色 :老爸是家里的顶梁柱
father name : 老爸 father 的角色 :老爸是家里的顶梁柱
son1 name : 儿子 son1 的角色 :儿子是未来的希望

图解:
在这里插入图片描述

从这个例子中可以看出,修改了儿子的类变量name 和 role 后,父类的 name 和 role 并没有发生变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值