Javascript 重新访问Python私有实例数据
我读过各种“Python实例中没有真正的私有数据”的帖子,但我们都知道在Perl和JavaScript中使用闭包可以有效地实现私有数据。那么为什么不用Python呢 例如:Javascript 重新访问Python私有实例数据,javascript,python,perl,closures,private,Javascript,Python,Perl,Closures,Private,我读过各种“Python实例中没有真正的私有数据”的帖子,但我们都知道在Perl和JavaScript中使用闭包可以有效地实现私有数据。那么为什么不用Python呢 例如: import codecs class Secret: def __private(): secret_data = None def __init__(self, string): nonlocal secret_data if s
import codecs
class Secret:
def __private():
secret_data = None
def __init__(self, string):
nonlocal secret_data
if secret_data is None:
secret_data = string
def getSecret(self):
return codecs.encode(secret_data, 'rot_13')
return __init__, getSecret
__init__, getSecret = __private()
现在我们做到了:
>>> thing = Secret("gibberish")
>>> thing.getSecret()
'tvoorevfu'
>>> dir(thing)
['_Secret__private', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'getSecret']
您可以对实例做什么来获得对原始字符串的读访问权(忽略我的弱加密)或写访问权
本周我在教我的学生Python课程,我试图理解为什么在给定闭包的情况下,JavaScript和Perl技术不适用于Python。您通常不会这样做,但可以使用模块
inspect
深入研究实例
>>> thing = Secret("gibberish")
>>> thing.getSecret()
'tvoorevfu'
>>> import inspect
>>> inspect.getclosurevars(thing.getSecret).nonlocals['secret_data']
'gibberish'
>>> inspect.getclosurevars(thing.__init__).nonlocals['secret_data']
'gibberish'
给定闭包中的一个函数,可以访问闭包的变量。我还没有找到修改变量的方法
所以,如果你愿意付出一些努力,这不是不可能的。我不知道为什么在正常的编程过程中会这样做。如果您只想访问原始版本,这并不难,因为Python函数实现了一个相当彻底的检查api。您可以通过以下方式访问原始机密:
thing = Secret("gibberish")
# __init__ doesn't need to be used here; anything defined within the closure will do
thing.__init__.__func__.__closure__[0].cell_contents
还有,嘿!我们得到原始值
修改该值比较困难,但并非不可能(请参阅)。已为此设置修改:
import ctypes
...
thing = Secret("gibberish")
cell = ctypes.py_object(thing.__init__.__func__.__closure__[0])
new_value = ctypes.py_object('whatever')
ctypes.pythonapi.PyCell_Set(cell, new_value)
thing.getSecret()
谢谢@mhawke,我使用inspect模块强化了我的原始示例,但担心某些向导仍会使用它闯入。谢谢@ig0774,我已将init修复为不再是setter。您的链接似乎不适合于此讨论。我很高兴看到Python实现了它的目标,“有不止一种方法可以做到这一点。”座右铭——哦,等等,没关系。@cdlane:不知怎的,我想要的链接不是最终的链接。我已将其更新到正确的链接。基本上,您必须使用C API,但这仍然是可能的。@cdlane:请参阅我最近的编辑,该编辑演示了如何将单元格值设置为几乎任意的Python对象。如果您降到C级别,我不能通过将隐藏的数据移到C级别来进行计数,而只能让您降到C级别以下的机器代码来再次对我进行计数。您和mhawke都很容易让我相信,没有读保护,写保护可能是特定于实现的。也许Perl和JavaScript只是一个很好的内省包,它们也不能依靠闭包来隐藏数据。再次感谢。我想,根据这里使用的标准,即使是Java或C#也没有“真正”的私有数据,因为您可以使用反射或拖放到IL来覆盖任何内容,但这两种语言的标准环境都提供了控制访问级别的方法(通过代码签名等)。我认为更广泛的一点是,Python解释器不努力隐藏任何正在执行的代码,事实上,它不遗余力地公开了大量关于解释器正在做什么的信息。