一、概要
在class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑,对于每一个类的成员(属性,字段,方法)的修饰符有两种
- 公开成员,在任何地方都能访问,即可在类外面和对象调用方法进行访问;
- 私有成员,只有在类的内部才能访问;
二、为什么要有修饰符
- 我们在一个类当中会产生很多的变量、属性、方法。其中有些是只能这个类自己用的,某些是可以允许其他程序使用的。如果在别的程序在调用当中对类的对象当中某些关键属性进行了改动,可能会导致这个对象无法正常工作。这是相当危险的。
- 而且把应该提供出去的方法属性和不能提供出去的方法属性相区别出,也体现了这个类的封装性。一个类模块只向外提供应该提供的功能而把其他无关紧要的内容屏蔽掉。因为一个工程可能不只有一个人在做,有的时候有多个人在做,这个时候就要求各个模块要有一定的封装性,其他程序员在做的时候不至于误操作,而且一看就明白了这个模块可以提供哪些功能。
三、语法格式
object
(公开成员)上面所讲的都是公开的成员
_object
(私有成员)Python中没有真正的私有字段或方法, 为了实现类似于c++中私有方法,
可以在你想声明为私有的方法和属性前加上单下划线,以提示该属性和方法不应在外部调用。
如果真的调用了也不会出错,但不符合规范
__object
(私有成员)- 私有成员命名时,前两个字符是下划线,只有自己的类内部能访问,继承的父类,子类均不能访问
- 真正作用是用来避免子类覆盖其内容(后面继承具体举例)
__object__
私有成员,系统专用。特殊成员除外,例如:
__init__
、__call__
、__dict__
等
四、举个栗子
4.1 、修饰普通字段
公有字段
1
2
3
4
5
6
7class Person(object):
def __init__(self, name):
self.name = name
if __name__ == '__main__':
person = Person('小明')
print(person.name)私有字段单下划线 “_”
1
2
3
4
5
6
7
8
9class Person(object):
def __init__(self, name):
self._name = name
if __name__ == '__main__':
'''测试代码'''
person = Person('小明')
# ====能正常访问,但会出现语法警告
print(person._name)私有字段 双下划线 “__”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Person(object):
def __init__(self, name):
self.__name = name
# 通过方法内部调用 self.__name
def get_name(self):
return self.__name
if __name__ == '__main__':
'''测试代码'''
person = Person('小明')
# ====能正常访问,但会出现语法警告 ====
# print(person.__name)
print(person.get_name())
# 外部无法访问
print(person.__name) #程序出错
# 强制调用私有变量,通过 对象._类名__私有变量名(注意:请不要在开发中这么去使用)
print(person._Person__name)
4.2 、修饰静态字段
栗子1
1
2
3
4
5
6
7
8
9
10
11
12
13
14class Test(object):
__static_var = '私有的静态变量'
def show(self):
print(Test.__static_var)
if __name__ == '__main__':
'''测试代码'''
#Test.__name # 类访问 ==> 错误
obj = Test()
# 通过对象强制调用(注意:请不要在开发中这么去使用)
print(obj._Test__static_var)
obj.show() # 类内部可以访问 ==> 正确
4.3、修饰方法
栗子1
1
2
3
4
5
6
7
8
9class Test(object):
def __method(self):
print("私有普通方法")
if __name__ == '__main__':
# 报错
obj.__method()
# 强制调用(注意:请不要在开发中这么去使用)
obj._Test__method()
4.4、其它成员类似
4.5、__xx__
此种写法为Python内建属性方法,不要去使用这种方式命名