柠檬班 2020-02-18
在属性和方法前加上 __ 两个下划线,将公共属性、实例属性、方法全部变成私有,这就是封装。
__属性,变私有属性
__self.属性,变私有属性
__方法,变私有方法
有更多的描述来说明封装的优点,便于理解。比如:
1、防止该类的代码和数据被外部类定义的代码随机访问。
2、要访问该类的代码和数据,必须通过严格的接口控制。
3、方便我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
4、适当的封装可以让程式码更容易理解与维护,也加强了代码数据的安全性。
5、良好的封装能够减少耦合。
6、类内部的结构可以自由修改
7、可以对成员变量进行更精确的控制。
8、隐藏信息,实现细节。
那么,封装的原则,也就是封装使用的标准就是:
1、属性都进行隐藏,提供公共方法来进行访问;
2、将不需要对外提供的属性和方法都隐藏起来。
私有变量和私有方法的使用方法
class Person(object): def __init__(self, name, age): self.name = name self.age = age self.__life = 100 #私有属性, 加两个下划线 外部不能访问,在类内部可以访问 def get_life(self): # 只能返回,不能修改 只读权限 print(‘life = ‘,self.__life) return self.__life def got_attack(self): # 对私有属性进行封装,是能通过方法去修改私有变量 self.__life -= 20 print(‘被攻击,减20滴血‘) self.__breath() # 挨打了,但是还是可以呼吸 return self.__life def __breath(self): # 私有方法,只能内部调用 print(‘呼吸‘) if __name__ == ‘__main__‘: a = Person(‘w‘,20) a.get_life() a.got_attack() # 强行调用:实例名._类名+方法名() a._Person__breath() # 强行修改:私有属性 a._Person__life = 800 a.get_life() # 新增一个私有属性,这个属性只有实例a有,实例b是没有的 b = Person(‘ggg‘,40) a.__money = 10000 print(a.__money) # 10000 # print(b.__money) #‘Person‘ object has no attribute ‘__money‘
这种自动变形的特点:
1.类中定义的x只能在内部使用,如self.x,引用的就是变形的结果。
2.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
3.在子类定义的x不会覆盖在父类定义的x,因为子类中变形成了:子类名__x,而父类中变形成了:父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。
这种变形需要注意的问题是:
1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:类名_属性,然后就可以访问了,如a._A__N
2.变形的过程只在类的内部生效,在实例化后再定义的赋值操作,不会变形