在Python中,如何阻止实例变量的外部修改?

在Python中,如何阻止实例变量的外部修改?,python,matplotlib,private,Python,Matplotlib,Private,我的理解是Python中没有真正的私有方法/属性,这意味着只要知道方法或属性的名称,您就可以访问和/或修改它(我可能错误地理解了隐私的概念) 考虑到上述框架,我遇到了一个我无法完全理解的情况。创建matplotlib.pyplotplot时: import numpy as np import matplotlib.pyplot as plt import matplotlib fig, ax = plt.subplots() x = np.arange(100) ax.plot(x, np

我的理解是Python中没有真正的私有方法/属性,这意味着只要知道方法或属性的名称,您就可以访问和/或修改它(我可能错误地理解了隐私的概念)

考虑到上述框架,我遇到了一个我无法完全理解的情况。创建
matplotlib.pyplot
plot时:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib

fig, ax = plt.subplots()

x = np.arange(100)
ax.plot(x, np.sin(x), label='sinus')
ax.legend()
我得到一个
matplotlib.legend.legend
对象,其中包含与图例中显示的文本条目相似的所有
matplotlib.text.text
对象的列表:

>>> fig.axes[0].legend()
<matplotlib.legend.Legend at 0x28f6aa4d898>
>>> fig.axes[0].legend().get_texts()
<a list of 1 Text objects>
>>> fig.axes[0].legend().get_texts()[0]
<matplotlib.text.Text at 0x28f6aa17198>
>>> print(fig.axes[0].legend().get_texts()[0])
Text(0,0,'sinus')
我不是Python方面的专家,但我并不期望出现这种行为,我不明白这在对象/属性级别是如何发生的,我也没有深入了解在
matplotlib.legend.legend.text
实例变量的构造中是否存在任何特殊约束

发生这种情况的唯一一般原因是,在某种深度上,有一种“幽灵”setter不修改类属性:

class Foo:

    def __init__(self, value):
        self._x = value

    @property
    def x(self): 
        return self._x

    @x.setter
    def x(self, value):
        # This setter blocks outside access
        pass
此设置程序阻止从外部进行控制以修改变量值:

>>> f = Foo(3)
>>> f.x
3
f.x = 5
>>> f.x
3
尽管如此,
matplotlib.legend.legend
实例变量
self.text
似乎定义为一个常规实例变量,我还没有找到它定义为属性或与之相关的任何getter或setter

因此,在这种情况下,我有三个问题:

1) 从属性无法修改的意义上讲,这个小类示例是获得“某种”隐私的公认/合法的方式吗

2) 在Python中是否有其他/等效的方法阻止对属性或方法的访问/控制

3) 它是如何工作的,或者在
matplotlib.legend.legend
对象的特定情况下是如何安排的(关注
self.text
实例变量)

考虑事项:

1) 我试图找到这些问题的答案,但没有成功。特别是关于如何在
matplotlib.legend.legend
对象中实现此行为的问题,我仍然没有回答

2) 我已经查看了
matplotlib.legend.legend
源代码,我可以看到函数
matplotlib.legend.legend.get_text()
返回一个
silent_list
对象,它显然只是一个具有重写的
\u repr\u
方法的列表对象。仍然不能帮助我理解我的思念

3) 我知道
matplotlib.legend.legend
对象中有一系列更高级的方法,允许我以多种/所有可能的方式修改图例。我只是想了解引擎盖下的机械装置是如何工作的


非常感谢您的时间和帮助。

这与属性机器无关。每次调用
legend()
都会得到不同的对象。这些对象具有不同的属性,因此使用一个
legend()
返回值拧紧不会自动影响另一个。

这与属性机制无关。每次调用
legend()
都会得到不同的对象。这些对象具有不同的属性,因此使用一个
legend()
返回值拧紧不会自动影响另一个。

我怀疑每次仅使用
.legend()
返回一个不同的对象。您可能可以很容易地测试出来。我怀疑只要
.legend()
每次都返回一个不同的对象。您可以很容易地测试它。实际上,
.legend()
创建了一个新实例。这是故意的;您可能需要更新绘图,只需再次调用
.legend()
,这将为您生成一个新的更新图例。要获取现有图例,最好首先使用句柄,
leg=ax.legend()
,然后再使用它,或者,如果不可能,使用
ax.get_legend()
获取现有图例。实际上,
.legend()
会创建一个新实例。这是故意的;您可能需要更新绘图,只需再次调用
.legend()
,这将为您生成一个新的更新图例。要获取现有图例,最好首先使用句柄,
leg=ax.legend()
,然后再使用它,或者如果不可能,使用
ax.get_legend()
获取现有图例。
>>> f = Foo(3)
>>> f.x
3
f.x = 5
>>> f.x
3