我们来看看一个很普通的类的继承:
class Model:
name = "DNN"
def __init__(self, name):
self.name = name
def print_name(self):
print(self.name)
@classmethod
def print_cls_name(cls):
print(cls.name)
class CNNModel(Model):
name = "CNN"
def main():
cnnmodel = CNNModel("Lenet")
cnnmodel.print_name()
CNNModel.print_cls_name()
if __name__ == '__main__':
main()
大家都很容易猜出结果:
Lenet
CNN
但是,我们再看看另一个代码:
class Model:
__name = "DNN"
def __init__(self, name):
self.__name = name
def print_name(self):
print(self.__name)
@classmethod
def print_cls_name(cls):
print(cls.__name)
class CNNModel(Model):
__name = "CNN"
def main():
cnnmodel = CNNModel("Lenet")
cnnmodel.print_name()
CNNModel.print_cls_name()
if __name__ == '__main__':
main()
此时,结果便不是我们预期那样:
Lenet
DNN
我们使用 __
隐藏了 name
的类变量,此时,类变量 __name
被牢牢的绑定在了父类上,子类无法更改。所以便出现了这样的情况。
更专业的说法:
- 以单下划线开头,表示这是一个保护成员,只有类对象和子类对象自己能访问到这些变量。以单下划线开头的变量和函数被默认是内部函数,使用
from module import *
时不会被获取,但是使用import module
可以获取。 - 以单下划线结尾仅仅是为了区别该名称与关键词
- 双下划线开头,表示为私有成员,只允许类本身访问,子类也不行。在文本上被替换为
_class__method
- 双下划线开头,双下划线结尾。一种约定,Python 内部的名字,用来区别其他用户自定义的命名,以防冲突。是一些 Python 的“魔术”对象,表示这是一个特殊成员,例如:定义类的时候,若是添加
__init__
方法,那么在创建类的实例的时候,实例会自动调用这个方法,一般用来对实例的属性进行初使化,Python 不建议将自己命名的方法写为这种形式。即以双下划线开头的方法和变量不会被继承