经典的面向对象语言,如 C++和 Java,通过公共、私有和受保护的关键字来控制对类资源的访问。类的私有成员被拒绝从类外的环境访问。它们只能在类内处理。
公众成员
公共成员(通常是在类中声明的方法)可以从类外部访问。调用公共方法需要同一个类的对象。私有实例变量和公共方法的这种安排确保了数据封装的原则。
默认情况下,Python 类中的所有成员都是公共的。任何成员都可以从类环境之外访问。
Example: Public Attributes
class Student:
schoolName = 'XYZ School' # class attribute
def __init__(self, name, age):
self.name=name # instance attribute
self.age=age # instance attribute
您可以访问Student
类的属性,也可以修改它们的值,如下所示。
Example: Access Public Members
>>> std = Student("Steve", 25)
>>> std.schoolName
'XYZ School'
>>> std.name
'Steve'
>>> std.age = 20
>>> std.age
20
受保护成员
一个类的受保护成员可以从该类内部访问,并且也可用于其子类。不允许其他环境访问它。这使得父类的特定资源能够被子类继承。
Python 让实例变量受保护的惯例是给它添加前缀 _(单下划线)。 这有效地防止了它被访问,除非它来自子类。
Example: Protected Attributes
class Student:
_schoolName = 'XYZ School' # protected class attribute
def __init__(self, name, age):
self._name=name # protected instance attribute
self._age=age # protected instance attribute
事实上,这并不妨碍实例变量访问或修改实例。您仍然可以执行以下操作:
Example: Access Protected Members
>>> std = Student("Swati", 25)
>>> std._name
'Swati'
>>> std._name = 'Dipa'
>>> std._name
'Dipa'
但是,您可以使用属性装饰器定义一个属性,并使其受到保护,如下所示。
Example: Protected Attributes
class Student:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self,newname):
self._name = newname
上图,@property decorator 用于将name()
方法作为属性,@name.setter
decorator 用于将name()
方法的另一个重载作为属性设置器方法。现在,_name
受到保护。
Example: Access Protected Members
>>> std = Student("Swati")
>>> std.name
'Swati'
>>> std.name = 'Dipa'
>>> std.name
'Dipa'
>>> std._name # still accessible
上图,我们使用std.name
属性修改_name
属性。但是,它仍然可以在 Python 中访问。 因此,负责任的程序员不会从类外访问和修改以_
为前缀的实例变量。
私人成员
Python 没有任何机制可以有效地限制对任何实例变量或方法的访问。Python 规定了一个惯例,在变量/方法的名称前加一个或两个下划线,以模仿受保护和私有访问说明符的行为。
变量前面的双下划线__
使其成为私有的。 强烈建议不要在课外触碰。任何尝试都会导致属性错误:
Example: Private Attributes
class Student:
__schoolName = 'XYZ School' # private class attribute
def __init__(self, name, age):
self.__name=name # private instance attribute
self.__salary=age # private instance attribute
def __display(self): # private method
print('This is private method.')
Example:
>>> std = Student("Bill", 25)
>>> std.__schoolName
AttributeError: 'Student' object has no attribute '__schoolName'
>>> std.__name
AttributeError: 'Student' object has no attribute '__name'
>>> std.__display()
AttributeError: 'Student' object has no attribute '__display'
Python 执行私有变量的名称管理。每个带双下划线的成员都将被更改为_object._class__variable
。因此,它仍然可以从课外访问,但是应该避免这种做法。
Example:
>>> std = Student("Bill", 25)
>>> std._Student__name
'Bill'
>>> std._Student__name = 'Steve'
>>> std._Student__name
'Steve'
>>> std._Student__display()
'This is private method.'
因此,Python 提供了公共、受保护和私有访问修饰符的概念实现,但不像其他语言,如 C# 、Java、C++。*****