Python - 封装



封装是将属性和方法捆绑在单个单元中的过程。它是面向对象编程范例所基于的主要支柱之一。

我们知道类是用户定义的对象原型。它定义了一组能够处理数据的数据成员和方法

根据数据封装的原理,描述对象的数据成员对类外部的环境是隐藏的。它们只能通过同一类中的方法进行访问。另一方面,方法本身可以从类上下文外部访问。因此,对象数据被称为由方法封装。这样,封装会阻止对对象数据的直接访问。

在 Python 中实现封装

C++Java 等语言使用访问修饰符来限制对类成员(即变量和方法)的访问。这些语言具有关键字 public、protected 和 private 来指定访问类型。

如果可以从程序中的任何位置访问类成员,则称该类成员为公共成员。仅允许从类中访问私有成员。通常,方法定义为 public,而实例变量是 private。私有实例变量和公共方法的这种安排确保了封装的实现。

与这些语言不同,Python 没有规定来指定类成员可能具有的访问类型。默认情况下,Python 类中的所有变量和方法都是公共的,如以下示例所示。

示例 1

在这里,我们有一个 Employee 类,其中包含实例变量、name 和 age。此类的对象具有这两个属性。它们可以从类外部直接访问,因为它们是公共的。


class Student:
	 	def __init__(self, name="Rajaram", marks=50):
	 	 	 self.name = name
	 	 	 self.marks = marks

s1 = Student()
s2 = Student("Bharat", 25)

print ("Name: {} marks: {}".format(s1.name, s2.marks))
print ("Name: {} marks: {}".format(s2.name, s2.marks))

它将产生以下输出 -

Name: Rajaram marks: 50
Name: Bharat marks: 25

在上面的示例中,实例变量在类中初始化。但是,从类外部访问实例变量的值没有限制,这与封装原则相悖。

尽管没有关键字来强制可见性,但 Python 有一个以特殊方式命名实例变量的约定。在 Python 中,在变量/方法的名称前加上单下划线或双下划线,以模拟 protected 和 private 访问修饰符的行为。

如果变量以单个双下划线为前缀(例如“__age”),则实例变量为私有变量,同样,如果变量名称以单个下划线为前缀(例如“_salary")

示例 2

我们修改 Student 类。添加另一个实例可变 salary。通过将 name 设为 private 并将 marks 设为 private,为它们添加双下划线前缀。


class Student:

	 	def __init__(self, name="Rajaram", marks=50):
	 	 	 self.__name = name
	 	 	 self.__marks = marks
	 	def studentdata(self):
	 	 	 print ("Name: {} marks: {}".format(self.__name, self.__marks))
	 	 		
s1 = Student()
s2 = Student("Bharat", 25)

s1.studentdata()
s2.studentdata()
print ("Name: {} marks: {}".format(s1.__name, s2.__marks))
print ("Name: {} marks: {}".format(s2.__name, __s2.marks))

当您运行此代码时,它将生成以下输出 -

Name: Rajaram marks: 50
Name: Bharat marks: 25
Traceback (most recent call last):
File "C:\Python311\hello.py", line 14, in <module>
print ("Name: {} marks: {}".format(s1.__name, s2.__marks))
AttributeError: 'Student' object has no attribute '__name'

上面的输出清楚地表明,实例变量 name 和 age 可以通过类内声明的方法(studentdata() 方法)来访问,但双下划线前缀使变量成为私有变量,因此,在类外部访问它们是有限的,这会引发 Attribute 错误。

什么是名称修饰?

Python 不会完全阻止对私有数据的访问。它只是让程序员的智慧来思考,而不是编写任何从类外部访问它的代码。您仍然可以通过 Python 的名称修饰技术访问私有成员。

名称修饰是将带有双下划线的成员名称更改为 object._class__variable 形式的过程。如果需要,仍然可以从课堂外部访问它,但应避免这种做法。

在我们的示例中,私有实例变量 “__name” 通过将其更改为


 obj._class__privatevar

因此,要访问“s1”对象的“__marks”实例变量的值,请将其更改为“s1._Student__marks”。

将上述程序中的 print() 语句更改为 −


 print (s1._Student__marks)

它现在打印 50,即 s1 的标记。

因此,我们可以得出结论,Python 并没有完全按照面向对象编程的理论实现封装。它通过规定名称约定并让程序员在确实需要访问公共范围内的私有数据时使用名称修饰来适应它。