天天看点

python的私有属性与保护属性方法的继承

作者:AI侃科技之备课汗姆

在Python中,私有属性以双下划线开头,例如"__private_attribute"。保护属性以单下划线开头,例如"_protected_attribute"。私有属性和保护属性都是用来限制对类属性的访问权限。

当一个类被继承时,子类会继承父类的所有属性和方法,包括私有属性和保护属性。但是,子类无法直接访问父类的私有属性。这是因为Python会将私有属性名字进行名称修饰,例如"_classname__private_attribute",以防止子类修改父类的私有属性。

子类可以访问父类的保护属性,但是无法直接访问父类的私有属性。如果子类想要访问父类的私有属性,可以通过调用父类的公共方法来间接地访问私有属性。例如:

class Parent:
    def __init__(self):
        self.__private_attribute = 42
        self._protected_attribute = 13

    def get_private_attribute(self):
        return self.__private_attribute

class Child(Parent):
    def get_private_attribute_of_parent(self):
        return self.get_private_attribute()

parent = Parent()
child = Child()

print(parent._protected_attribute)  # 输出: 13
print(child._protected_attribute)   # 输出: 13

# 下面两行代码会报错,因为私有属性是不能直接访问的
#print(parent.__private_attribute)
#print(child.__private_attribute)

print(child.get_private_attribute_of_parent())  # 输出: 42
           

在子类中,可以通过调用父类的公共方法来访问父类的私有属性。在这个例子中,子类Child调用了父类Parent的公共方法get_private_attribute(),并通过该方法返回父类的私有属性值。

有一个Teacher类表示教师,它有一个私有属性__name和一个保护属性_salary。我们还有一个子类Professor表示教授,它继承了Teacher类。现在我们来看一下如何在子类中访问父类的私有属性和保护属性。

class Teacher:
    def __init__(self, name, salary):
        self.__name = name
        self._salary = salary

    def get_name(self):
        return self.__name

    def get_salary(self):
        return self._salary


class Professor(Teacher):
    def __init__(self, name, salary, research_area):
        super().__init__(name, salary)
        self.research_area = research_area

    def get_name(self):
        return f"Professor {self._Teacher__name}"   # 使用父类的私有属性,需要进行名称修饰

    def get_research_area(self):
        return self.research_area

teacher = Teacher("Alice", 50000)
professor = Professor("Bob", 80000, "Computer Science")
print(teacher.get_name())      # 输出: Alice
print(teacher.get_salary())    # 输出: 50000
print(professor.get_name())    # 输出: Professor Bob
print(professor.get_salary())  # 输出: 80000
print(professor.get_research_area())  # 输出: Computer Science
 
           

在这个例子中,Teacher类有一个私有属性__name和一个保护属性_salary。Professor类继承了Teacher类,并添加了一个research_area属性。在Professor类中,我们重写了get_name()方法来使用父类的私有属性。我们可以看到,在子类中通过调用父类的公共方法来访问父类的保护属性。

其中

def get_name(self):
        return f"Professor {self.__name}"   # 使用父类的私有属性,需要进行名称修饰           

如果不修饰为return f"Professor {self._Teacher__name}" # 。如果我们直接使用self.__name来访问父类的私有属性,会导致AttributeError异常。因为Python会将私有属性的名称进行名称修饰,以防止子类修改父类的私有属性。