Python 简明教程

Python - Access Modifiers

Python access modifiers 用于限制对类中成员(即变量和方法)的访问。有三种类型的访问修饰符,即 public、protected 和 private。

  1. Public members − 如果类成员可以在程序中的任何地方访问,则该成员被称为 public。

  2. Protected members − 它们既可以从类内访问,也可以从派生自该类的类中访问。

  3. Private members − 它们只能在类内访问。

通常,方法被定义为公有方法,而实例变量则为私有变量。私有实例变量和公有方法的这种安排确保了封装原则的实施。

Access Modifiers in Python

与 C++ 和 Java 不同,Python 不使用 Public、Protected 和 Private 关键字来指定访问修饰符的类型。默认情况下,Python 类中的所有变量和方法都是公有的。

Example

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

class Employee:
   'Common base class for all employees'
   def __init__(self, name="Bhavana", age=24):
      self.name = name
      self.age = age

e1 = Employee()
e2 = Employee("Bharat", 25)

print ("Name: {}".format(e1.name))
print ("age: {}".format(e1.age))
print ("Name: {}".format(e2.name))
print ("age: {}".format(e2.age))

它将生成以下 output

Name: Bhavana
age: 24
Name: Bharat
age: 25

Python 不会强制限制访问任何实例变量或方法。然而,Python 规定了一个惯例,用单下划线或双下划线作为变量/方法名称的前缀,以模拟受保护和私有访问修饰符的行为。

  1. 要表示实例变量为私有变量,请在变量名前加上双下划线(比如,“__age”)。

  2. 要暗示某个实例变量是受保护的,请在变量名前加上单下划线(比如,“_salary”)。

Another Example

让我们修改 Employee 类。添加另一个实例变量 salary。通过分别加上双下划线和单下划线前缀将 age 设置为私有的,将 salary 设置为受保护的。

class Employee:
   def __init__(self, name, age, salary):
      self.name = name # public variable
      self.__age = age # private variable
      self._salary = salary # protected variable
   def displayEmployee(self):
      print ("Name : ", self.name, ", age: ", self.__age, ", salary: ", self._salary)

e1=Employee("Bhavana", 24, 10000)

print (e1.name)
print (e1._salary)
print (e1.__age)

当您运行此代码时,它将生成以下 output

Bhavana
10000
Traceback (most recent call last):
 File "C:\Users\user\example.py", line 14, in <module>
  print (e1.__age)
        ^^^^^^^^
AttributeError: 'Employee' object has no attribute '__age'

Python 显示 AttributeError 是因为 __age 为私有,且不可在类外使用。

Name Mangling

Python 不会阻止对私有数据的访问,它仅仅留给程序员的智慧,不会编写任何可以从类外访问它的代码。您仍然可以通过 Python 的名称混淆技术访问私有成员。

名称混淆是将双下划线成员的名称更改为 object._class__variable 格式的过程。如果需要,仍然可以从类外访问它,但应该避免此做法。

在我们的示例中,私有实例变量 "__name" 混淆后变为 −

obj._class__privatevar

因此,要获取 "e1" 对象的 "_age" 实例变量值,请将其更改为 "e1._Employee_age"。

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

print (e1._Employee__age)

它现在打印 24,即 e1 的年龄。

Python Property Object

Python 的标准库有一个内置的 property() 函数。它返回一个属性对象。它充当 Python 类的实例变量的接口。

面向对象编程的封装原则要求实例变量具有受限制的私有访问。Python 没有高效的机制用于此目的。property() 函数提供了一个替代方案。

property() 函数使用在类中定义的 getter、setter 和 delete 方法来为类定义一个属性对象。

Syntax

property(fget=None, fset=None, fdel=None, doc=None)

Parameters

  1. fget − 一个用于获取实例变量值的实例方法。

  2. fset − 一个用于向实例变量分配值的实例方法。

  3. fdel − 一个用于删除一个实例变量的实例方法。

  4. fdoc − 该属性的文档字符串。

该函数使用 getter 和 setter 方法以返回属性对象。

Getters and Setter Methods

getter 方法获取一个实例变量的值,通常命名为 get_varname,而 setter 方法给这个变量赋值,命名为 set_varname。

Example

让我们给 Employee 类中定义 getter 方法 get_name() 和 get_age(),以及 setter 方法 set_name() 和 set_age()。

class Employee:
   def __init__(self, name, age):
      self.__name = name
      self.__age = age

   def get_name(self):
      return self.__name
   def get_age(self):
      return self.__age
   def set_name(self, name):
      self.__name = name
      return
   def set_age(self, age):
      self.__age=age

e1=Employee("Bhavana", 24)
print ("Name:", e1.get_name(), "age:", e1.get_age())
e1.set_name("Archana")
e1.set_age(21)
print ("Name:", e1.get_name(), "age:", e1.get_age())

它将生成以下 output

Name: Bhavana age: 24
Name: Archana age: 21

getter 和 setter 方法可以获取或给实例变量赋值。property() 函数利用它们添加属性对象作为类属性。

name 属性的定义如下 −

name = property(get_name, set_name, "name")

类似地,你可以添加 age 属性 −

age = property(get_age, set_age, "age")

属性对象的一个优势是你可以利用它来检索其关联的实例变量的值以及指定值。

例如,

print (e1.name) displays value of e1.__name
e1.name = "Archana" assigns value to e1.__age

Example

包含属性对象及用法的完整程序如下 −

class Employee:
   def __init__(self, name, age):
      self.__name = name
      self.__age = age

   def get_name(self):
      return self.__name
   def get_age(self):
      return self.__age
   def set_name(self, name):
      self.__name = name
      return
   def set_age(self, age):
      self.__age=age
      return
   name = property(get_name, set_name, "name")
   age = property(get_age, set_age, "age")

e1=Employee("Bhavana", 24)
print ("Name:", e1.name, "age:", e1.age)

e1.name = "Archana"
e1.age = 23
print ("Name:", e1.name, "age:", e1.age)

它将生成以下 output

Name: Bhavana age: 24
Name: Archana age: 23