Discuss / Python / 在继承和私有属性名字的问题上碰到一些疑问

在继承和私有属性名字的问题上碰到一些疑问

Topic source

bzny虫

#1 Created at ... [Delete] [Delete and Lock User]

如果不进行属性名字私有化,没有任何问题:

class animal(object):

    def __init__(self,name):   #实例初始化,传入name属性,以name为变量名储存

        self.name=name

    def run(self):

        print("%s is running" %self.name)  #调用name进行输出

class cat(animal):

    def __init__(self, name):  #通过重写一遍__init__方法的方式初始化

        self.name=name

class dog(animal):

    def __init__(self, name):  #通过引用父类的__init__方法的方式初始化

        super().__init__(name)

a=cat('aa')

a.run()

b=dog('bb')

b.run()

不论通过何种方式初始化,都没有问题, 都能正常调用属性。但如果我们用私有属性方式初始化:

class animal(object):

    def __init__(self,name):   #实例初始化,传入name属性,以_animal__name为变量名储存

        self.__name=name

    def run(self):

        print("%s is running" %self.__name)  #调用_animal__name进行输出

class cat(animal):

    def __init__(self, name):  #通过重写一遍__init__方法的方式初始化,此时name储存的名字是_cat__name,再调用父类的run方法就会出错,只能重写一遍run方法,让run调用_cat__name

        self.__name=name

    def run(self):

        print("%s is running" %self.__name)

class dog(animal):

    def __init__(self, name):  #通过引用父类的__init__方法的方式初始化,此时name储存的名字和父类一样是_animal__name,可以直接使用父类的run方法,但是如果要自己再增加方法

        super().__init__(name) #比如增加一个eat,输出xx在吃则要写成print("%s is eating" %self._animal__name ),如果直接调用self.__name,则会出错

a=cat('aa')

a.run()

b=dog('bb')

b.run()

既然继承的目的是为了让代码更精简好用、减少工作量,那cat里那种全部重写一遍代码应该不是设计初衷,但如果采取第二种,就意味着所有的变量都要采取_父类__属性的命名方式存储,而如果子类中要增加新的属性,则也要手动命名为_父类__属性这种格式,不然的话有些属性是_父类__属性,而子类新加属性是_子类__属性这种命名格式,则容易产生混乱。

如果要避免这种麻烦,也许不要无脑使用私有属性才是正解。


  • 1

Reply