Python - 面向对象编程 - 公共属性、保护属性、私有属性
公共属性
在 Python 的类里面,所有属性和方法默认都是公共的
class PoloBlog: # 公共属性 sum = 0 # 构造方法 def __init__(self, name): self.name = name # 公共方法 def test(self): ...
但Python也可以设置受保护、私有类型的变量or方法
私有类型的属性、方法
- 在实际开发中,对象的某些属性或方法可能只希望在对象的内部被使用,而不希望在外部被访问到
- 私有属性:就是对象不希望公开访问的属性
- 私有方法:就是对象不希望公开访问的方法
定义方式,类图
在属性、方法名前加两个下划线就是私有属性、私有方法了
代码
# 私有属性、方法 class Person: # 构造方法 def __init__(self, name, age): self.name = name self.__age = age # 实例方法 def pinrtMsg(self): print("name:", self.name, " age:", self.__age) # 私有方法 def __getAge(self): print("age is ", self.__age) person = Person("小菠萝", 24) # 直接调用私有属性、私有方法 - 会报错 print(person.__age) print(person.__getAge) # 输出结果 print(person.__age) AttributeError: 'Person' object has no attribute '__age' print(person.__getAge) AttributeError: 'Person' object has no attribute '__getAge'
看看 Pycharm 的代码联想
压根不会联想,因为是私有属性、私有方法,不允许在对象外部被使用
通过公共方法访问私有属性
person = Person("小菠萝", 24) person.printMsg() # 输出结果 name: 小菠萝 age: 24
类属性私有化
# 类属性的私有化 class Person: __sum = 0 @classmethod def getSum(cls, num): # 调用私有类方法 cls.__sumAdd(num) print(cls.__sum) @classmethod def __sumAdd(cls, num): cls.__
重点
- 子类无法访问父类的私有变量、方法
- 私有变量只有本类的内部能直接调用
- But!外部真的不能访问吗?
伪私有属性和私有方法
- 其实 Python 中,并没有真正意义上的私有,仍然可以在外部访问私有属性、私有方法
- 因为,在给私有属性、方法命名时,实际是对名称做了一些特殊处理,使得外界无法访问到
- 处理方式:在名称前面加上 _类名 ,私有属性、方法就会变成 _类名__名称
# 间接调用 class Person: __sum = 0 # 构造方法 def __init__(self, name): self.__name = name # 私有方法 def __getName(self): print("name is ", self.__name) # 调用类私有属性 print(Person._Person__sum) person = Person("小菠萝") # 调用私有属性 print(person._Person__name) # 调用私有方法 person._Person__getName() # 输出结果 0 小菠萝 name is 小菠萝
无论是类对象还是实例对象,都可以通过 ._类名__名称 来调用私有属性、方法,这算是一种间接调用
受保护类型的属性、方法
- 受保护类型一般会称为:protect 属性,学过 Java 的应该都了解
- 在属性和方法前加一个下划线就是 protect 类型了,私有类型是两个下划线
# 受保护类型 class PoloBlog: _sum = 0.0 # 构造方法 def __init__(self, name): self._name = name # 保护方法 def _printName(self): print(self._name) # 类方法 @classmethod def _classMethod(cls): print(cls._sum) blog = PoloBlog("小菠萝") # 打印保护类型的类属性 print(PoloBlog._sum) # 打印保护类型的实例属性 print(blog._name) # 实例对象调用保护类型的实例方法 blog._printName() # 实例对象调用保护类型的类方法 blog._classMethod() # 类对象调用保护类型的类方法 PoloBlog._classMethod() # 输出结果 0.0 小菠萝 小菠萝 0.0 0.0
知识点
- 父类的 protect 属性,子类可以继承
- 实例对象、类对象都能直接调用 protect 属性、方法
总的来说,和公共变量没有什么特别大的区别
总结
无论是受保护型变量还是私有变量,其实在外部还是能访问的,所以并不能真正控制属性的访问权限