Python-封装


封装原则是面向对象编程范式的主要支柱之一。Python 采用不同的方法来实现封装。

我们知道类是用户定义的对象原型。它定义了一组能够处理数据的数据成员和方法。根据数据封装的原理,描述对象的数据成员对类外部的环境是隐藏的。它们仅可用于处理类中定义的方法。另一方面,方法本身可以从外部类上下文访问。因此,对象数据被称为由方法封装。这种封装的结果是防止对对象数据的任何未经授权的访问。

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

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

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

实施例1

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

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中,用单下划线或双下划线作为变量/方法名称的前缀来模拟受保护和私有访问修饰符的Behave。

如果变量以单个双下划线为前缀(例如“ __age ”),则实例变量是私有的,类似地,如果变量名以单下划线为前缀(例如“ _salary ”)

实施例2

让我们修改Student 类。添加另一个实例变量salary。将名称设为私有,并通过在名称前添加双下划线将其标记为私有。

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()方法)访问它们,但由于双下划线前缀使变量私有,因此可以在外部访问它们该类是不允许的,引发属性错误。

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

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

在我们的示例中,私有实例变量“__name”通过将其更改为格式而被破坏

obj._class__privatevar

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

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

print (s1._Student__marks)

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

因此,我们可以得出结论,Python 并没有完全按照面向对象编程的理论来实现封装。它采用了一种更成熟的方法,规定了名称约定,并允许程序员在确实需要访问公共范围内的私有数据时使用名称修饰。