python学习交流

关于python类的继承的一个小坑

2018-12-07  本文已影响2人  水之心

我们来看看一个很普通的类的继承:

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 被牢牢的绑定在了父类上,子类无法更改。所以便出现了这样的情况。

更专业的说法:

  1. 以单下划线开头,表示这是一个保护成员,只有类对象和子类对象自己能访问到这些变量。以单下划线开头的变量和函数被默认是内部函数,使用 from module import * 时不会被获取,但是使用 import module 可以获取。
  2. 以单下划线结尾仅仅是为了区别该名称与关键词
  3. 双下划线开头,表示为私有成员,只允许类本身访问,子类也不行。在文本上被替换为 _class__method
  4. 双下划线开头,双下划线结尾。一种约定,Python 内部的名字,用来区别其他用户自定义的命名,以防冲突。是一些 Python 的“魔术”对象,表示这是一个特殊成员,例如:定义类的时候,若是添加 __init__ 方法,那么在创建类的实例的时候,实例会自动调用这个方法,一般用来对实例的属性进行初使化,Python 不建议将自己命名的方法写为这种形式。即以双下划线开头的方法和变量不会被继承
上一篇 下一篇

猜你喜欢

热点阅读