概述
Python 类的 public protected private
class A:
def __init__(self):
self.public_field = 5
self._protect_filed = 8
self.__private_field = 10
def get_private_filed(self):
return self.__private_field
obj = A()
print(obj.public_field) # 访问 public 属性
print(obj._protect_filed) # 访问 protected 属性
print(obj.__private_field) # 访问 private 属性会报错
# AttributeError: 'A' object has no attribute '__private_field'
修饰符 | 定义 | 用法 |
---|---|---|
public | 默认(不以下划线开头) | 可以被子类、类内以及类外被访问。 |
protected | 以单下划线开头 | 保护类型只能允许其本身与子类进行访问 |
private | 以双下划线开头 | 只能允许类内进行访问 |
魔法方法 | xx | python 内部定义的变量名 |
单下划线开头的成员,用一种习惯性的命名方式来表示该字段受保护,为了尽量减少无意间访问内部属性所带来的意外,本类之外的代码使用该字段时要小心。它本质上与 public 属性使用相同,但命名上体现了保护目的。
应该多用 protected 属性,并在文档里把这些字段的合理用法告诉子类开发者,而不要试图用 private 属性来限制子类访问这些字段。
class B(A):
def __init__(self):
super().__init__()
self._value = 10
childObj = B()
print(childObj._value)
print(childObj.public_field)
print(childObj._protect_filed)
应该主观上避免对 protected 属性的访问,但访问它也不会导致报错。
# 访问 private 属性会报错
# AttributeError: 'A' object has no attribute '__private_field'
obj.__private_field
但本类的方法可以直接访问它们:
obj.get_private_filed()
子类无法访问父类的 private 字段:
print(childObj.__private_filed)
#AttributeError: 'B' object has no attribute '__private_filed'
需要特殊说明的是,在 python 中没有像其他类似语言的 public, private 等关键字修饰。同时若方法或者变量是 private 类型时,其方法或者变量实际上是被转换了,转换规则是 在变量的前端插入类名,在类名前添加一个下划线"_",形成"_ClassName__变量名"。比如 A 的 __private_field 字段,实际上被变换成 _A__private_filed 字段,通过变换后属性名与被访问属性名不相符达到类之外或子类无法访问 private 属性目的。
print(obj._A__private_field)
print(childObj._A__private_field)
换句话说,Python 编译器无法严格保证 private 字段的私密性。
Python 为什么不从语法上严格保证 private 字段的私密性呢?用最简单的话讲,We are all consenting adults here(我们都是成年人了)。这也是很多 Python 程序员的观点,大家都认为开放要比封闭好。
另外一个原因在于 Python 语言本身就已经提供了一些属性挂钩(getattr 等),使得开发者能够按照自己的需要来操作对象内部的数据。既然如此,那为什么还要阻止访问 private 属性呢?
最后,不要盲目地将属性设为 private,而是应该从一开始就做好规划,并允许子类更多地访问超类的内部 API;只有当子类不受自己控制时,才考虑用 private 属性来避免命名冲突。
如果我们使用转换后的变量或者方法,我们仍然可以进行访问,即 python 没有严格意义上的 private 类型。
class C:
def __init__(self):
self.name = "class_def" # public
self.__age = 29 # private
self._sex = "man" # protected
def fun1(self):
print("call public function")
def __fun2(self):
print("call private function")
def _fun3(self):
print("call protected function")
if __name__ == "__main__":
obj = C() # 实例化类对象
obj.fun1()
obj._C__fun2()
obj._fun3()
print(obj._C__age)
print(obj._sex)
print(obj.name)
# error
# obj.__fun2()
# print(obj.__age)
输出结果:
call public function
call private function
call protected function
29
man
class_def
最后
以上就是可爱钢笔为你收集整理的Py public protected privatePython 类的 public protected private的全部内容,希望文章能够帮你解决Py public protected privatePython 类的 public protected private所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复