Python 公共、受保护、私有成员


经典的面向对象语言,如 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++。*****

评论关闭