私有属性和受保护属性
C ++和Java之类的经典面向对象语言通过公有(public)、私有(private)和受保护(protected)的关键字来控制对类资源的访问。类的私有成员拒绝从类外部环境访问。它们只能在类的内部处理。
可从类外部访问公有成员(通常是在类中声明的方法)。调用公有方法需要相同类的对象。私有实例变量和公共方法的这种安排确保了数据封装的原理。
类的受保护成员可以从该类内部访问,也可以用于其子类。不允许其他环境访问它。这样可以使子类继承父类的特定资源。
Python没有有效限制访问任何实例变量或方法的机制。 Python规定了在变量/方法名称前加单下划线或双下划线的约定,以模拟受保护和私有访问说明符的行为。
默认情况下,Python类中的所有成员都是公有的。可以从类环境之外访问任何成员。
Example: Public Attributes
class Employee:
def __init__(self, name, sal):
self.name=name
self.salary=sal
可以访问员工类的属性,也可以修改其值,如下所示。
e1=Employee("Kiran",10000)
e1.salary
10000
e1.salary=20000
e1.salary
20000
Python的实例变量受保护的约定是在其上添加前缀_
(单个下划线)。 这将约定防止对其进行访问, 除非访问来自子类。
Example: Protected Attributes
class Employee:
def __init__(self, name, sal):
self._name=name # protected attribute
self._salary=sal # protected attribute
实际上,这不会阻止实例变量访问或修改实例。 仍然可以执行以下操作:
e1=Employee("Swati", 10000)
e1._salary
10000
e1._salary=20000
e1._salary
20000
因此,负责的程序员应避免从其类的外部访问和修改以_
开头的实例变量。
同样,在变量前加上双下划线__
使其变为私有。 强烈建议不要在类外碰它。 尝试这样做会导致AttributeError:
Example: Private Attributes
class Employee:
def __init__(self, name, sal):
self.__name=name # private attribute
self.__salary=sal # private attribute
e1=Employee("Bill",10000)
e1.__salary
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-9-d5a2eb37a52c> in <module>
1 e1=Employee("Bill",10000)
----> 2 e1.__salary
AttributeError: 'Employee' object has no attribute '__salary'
Python执行私有变量的改名处理(name mangling)。 每个具有双下划线的成员将更改为_object._class__variable。 如果需要,仍然可以从类外部访问它,但是应该避免这种做法。
e1=Employee("Bill",10000)
e1._Employee__salary
10000
e1._Employee__salary=20000
e1._Employee__salary
20000