0%

Python_私有属性与受保护的属性

Python中除去常见的普通属性外还存在私有属性与受保护的属性.

这两种属性往往是设计者不希望他人看到的属性,在类设计过程中会采用下划线来标识.

私有属性双下划线开头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#Python中对以__开头的私有属性会进行改名操作,并存入实例__dict__属性中,其改名的策略为在其前面加一个下划线外加类名.
class vector:
# 实例构建方法中定义了三个属性,其中两个为私有属性一个为普通属性
def __init__(self , x, y ,z):
self.__x = x
self.__y = y
self.z = z
def __repr__(self):
class_name = type(self).__name__
return '{}({!r}, {!r} , {!r})'.format(class_name, *self)

def __str__(self):
return str(tuple(self))
# 发现在类定义里面,既可以使用改名前的私有属性,也可以使用改名后的私有属性
def __iter__(self):
return (i for i in (self.__x, self._vector__y , self.z))
vec = vector(3,4, 5)
print(vec)
# (3, 4, 5)
print(vec.__dict__)
# {'_vector__x': 3, '_vector__y': 4, 'z': 5}
print(vec._vector__x)
# 3
# 只能通过改名后的属性进行访问
print(vec.__x)
# AttributeError: 'vector' object has no attribute '__x'
  • 优点:Python会进行识别并进行改名操作,防止他人误操作

  • 缺点:不对称的名称规范,无法避免恶意操作,比如

    1
    2
    3
    4
    # 私有属性就是不想让他人进行访问,或者变更,结果你强行更改
    vec._vector__x = 8
    print(vec._vector__x)
    # 8

    受保护的属性单下划线开头

大多数Python程序员反对使用双下划线进行命名操作,于是提出使用单下划线前缀编写受保护的属性,约定不对单下划线进行访问.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class vector:
def __init__(self , x, y ,z):
self._x = x
self.__y = y
self.z = z
def __repr__(self):
class_name = type(self).__name__
return '{}({!r}, {!r} , {!r})'.format(class_name, *self)

def __str__(self):
return str(tuple(self))
def __iter__(self):
return (i for i in (self._x, self._vector__y , self.z))
vec = vector(3,4, 5)
print(vec)
print(vec.__dict__)
print(vec._x)
# (3, 4, 5)
# {'_x': 3, '_vector__y': 4, 'z': 5}
# 3

上面的代码实例可以看到单下划线的属性,Python解释器并没有对其进行改名操作,就当作普通属性,这就是一种约定而已.