在Python中,如何阻止实例变量的外部修改?
我的理解是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
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