python私有同名属性的继承

在python中以双下划线开头的属性是私有属性,不会被子类继承,然而python中的私有不是绝对的私有,可以通过_类名__私有属性的方式被继承,现有如下两个类, childFather

  • 第一种情况:子类Child未调用父类的构造函数,但是没有定义get方法,只定义了一个__value私有属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Father(object):

def __init__(self):
self.__value = 0

def get(self):
print 'Father get() method'
print self.__value


class Child(Father):

def __init__(self):
self.__value = 100

子类Child继承了父类Fatherget方法,但是这个get方法打印的是父类Father中的私有属性__value,子类对象创建的过程没有调用父类的构造函数,并未继承到父类的私有属性_Father__value,所以子类对象调用时会抛出异常AttributeError: 'Child' object has no attribute '_Father__value'

1
2
3
4
5
6
7
8
9
10
>>> c = Child()
>>> c.get()
Father get() method
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "fc.py", line 11, in get
print self.__value
AttributeError: 'Child' object has no attribute '_Father__value'
>>> dir(c)
['_Child__value', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get']
  • 第二种情况:子类Child调用了父类的构造函数,但是没有定义get方法,同时定义了一个__value私有属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Father(object):

def __init__(self):
self.__value = 0

def get(self):
print 'Father get() method'
print self.__value


class Child(Father):

def __init__(self):
super(Child, self).__init__()
self.__value = 100

子类Child通过调用父类Father的构造函数继承了父类的私有属性__value,同时自己也定义了一个同名的私有属性__value,但是继承而来的get方法使用的依然是父类的私有属性,即:_Father__value,所以c.get()结果为0

1
2
3
4
5
6
>>> c = Child()
>>> c.get()
Father get() method
0
>>> dir(c)
['_Child__value', '_Father__value', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get']
  • 第三种情况:子类Child调用了父类的构造函数,同时定义自己的get方法,但是没有定义自己__value私有属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Father(object):

def __init__(self):
self.__value = 0

def get(self):
print 'Father get() method'
print self.__value


class Child(Father):

def __init__(self):
super(Child, self).__init__()

def get(self):
print 'Child get() method'
print self.__value

子类Child实现了自己的get方法,希望使用自己的私有属性__value,因为是私有的,所以不会是继承自父类Father,所以即使调用了父类的构造方法继承得到的_Father__value在此也是无用的。

1
2
3
4
5
6
7
8
9
10
>>> c = Child()
>>> c.get()
Child get() method
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "fc.py", line 22, in get
print self.__value
AttributeError: 'Child' object has no attribute '_Child__value'
>>> dir(c)
['_Father__value', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get']
  • 第四种情况:子类Child调用了父类的构造函数,同时定义了自己的get方法,也定义自己__value私有属性,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Father(object):

def __init__(self):
self.__value = 0

def get(self):
print 'Father get() method'
print self.__value


class Child(Father):

def __init__(self):
super(Child, self).__init__()
self.__value = 100

def get(self):
print 'Child get() method'
print self.__value

子类Child实现了自己的get方法,而且定义了自己的私有属性__value,所以c.get()获取到的是子类自己的私有属性的值。

1
2
3
4
5
6
7
8
9
>>> c.get()
Child get() method
100
>>> dir(c)
['_Child__value', '_Father__value', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get']
>>> c._Child__value
100
>>> c._Father__value
0