Python程序中的私有变量
在本教程中,我们将学习Python **类**中的**私有变量**。
Python没有所谓的**私有变量**的概念。但是,大多数Python开发人员遵循一种命名约定来表明变量不是公共的,而是私有的。
我们必须以**双下划线**开头变量名来将其表示为私有变量(实际上并非如此)。例如:**one、two等等**。
正如我们已经说过的,名称以双下划线开头的变量并非私有。我们仍然可以访问它们。让我们看看如何创建私有类型的变量,然后我们将看到如何访问它们。
# creating a class class Sample: def __init__(self, nv, pv): # normal variable self.nv = nv # private variable(not really) self.__pv = pv # creating an instance of the class Sample sample = Sample('Normal variable', 'Private variable')
我们创建了一个类及其实例。我们在`__init__`方法中定义了两个变量,一个是普通的,另一个是私有的。现在,尝试访问这些变量,看看会发生什么。
示例
# creating a class class Sample: def __init__(self, nv, pv): # normal variable self.nv = nv # private variable(not really) self.__pv = pv # creating an instance of the class Sample sample = Sample('Normal variable', 'Private variable') # accessing *nv* print(sample.nv) # accessing *__pv** print(sample.__pv)
输出
如果运行以上代码,则会得到以下输出。
Normal variable --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-13-bc324b2d20ef> in <module> 14 15 # accessing *__pv** ---> 16 print(sample.__pv) AttributeError: 'Sample' object has no attribute '__pv'
程序显示了nv变量,没有任何错误。但是当我们尝试访问`__pv`变量时,我们得到了**AttributeError**。
为什么会出现此错误?因为没有名为`__pv`的属性。那么`__init__`方法中的`self.__pv = pv`语句呢?我们稍后会讨论这个问题。首先,让我们看看如何访问`__pv`变量。
我们可以访问任何名称以**双下划线**开头的类变量,方法是使用`_className__variableName_`。因此,在我们的示例中,它是`_Sample__pv_`。现在,使用`_Sample__pv_`名称访问它。
示例
# creating a class class Sample: def __init__(self, nv, pv): # normal variable self.nv = nv # private variable(not really) self.__pv = pv # creating an instance of the class Sample sample = Sample('Normal variable', 'Private variable') # accessing *nv* print(sample.nv) # accessing *__pv** using _Sample__pv name print(sample._Sample__pv)
输出
如果运行以上代码,则会得到以下结果。
Normal variable Private variable
为什么变量`__pv`的名称发生了变化?
在Python中,有一个名为名称改编(name mangling)的概念。Python会更改以**双下划线**开头的变量的名称。因此,任何名称以双下划线开头的类变量都会更改为`_className__variableName_`的形式。
因此,此概念也适用于类的 方法。您可以使用以下代码查看它。
示例
class Sample: def __init__(self, a): self.a = a # private method(not really) def __get_a(self): return self.a # creating an instance of the class Sample sample = Sample(5) # invoking the method with correct name print(sample._Sample__get_a()) # invoking the method with wrong name print(sample.__get_a())
输出
如果运行以上代码,则会得到以下结果。
5 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-19-55650c4990c8> in <module> 14 15 # invoking the method with wrong name ---> 16 print(sample.__get_a()) AttributeError: 'Sample' object has no attribute '__get_a'
结论
使用**双下划线**的目的不是为了限制访问变量或方法。它是为了表明该特定变量或方法仅旨在绑定在类内部。如果您对本教程有任何疑问,请在评论区提出。