有没有一个神奇的方法可以重载赋值操作符,比如__assign__(self, new_value)
我想禁止重新绑定一个实例:
class Protect():
def __assign__(self, value):
raise Exception("This is an ex-parrot")
var = Protect() # once assigned...
var = 1 # this should raise Exception()
有可能吗?这是不是很疯狂?我应该吃药吗?
发布于 2012-06-14 07:20:27
不,因为赋值是一个没有修改钩子的language intrinsic。
发布于 2012-06-14 07:20:10
我认为这是不可能的。在我看来,赋值给一个变量并不会对它之前引用的对象做任何事情:只是变量现在“指向”了一个不同的对象。
In [3]: class My():
...: def __init__(self, id):
...: self.id=id
...:
In [4]: a = My(1)
In [5]: b = a
In [6]: a = 1
In [7]: b
Out[7]: <__main__.My instance at 0xb689d14c>
In [8]: b.id
Out[8]: 1 # the object is unchanged!
但是,您可以通过使用引发异常的__setitem__()
或__setattr__()
方法创建包装器对象来模拟所需的行为,并将“不可更改”的内容保留在其中。
发布于 2018-09-21 15:25:17
在模块内部,这是完全可能的,通过一点黑魔法。
import sys
tst = sys.modules['tst']
class Protect():
def __assign__(self, value):
raise Exception("This is an ex-parrot")
var = Protect() # once assigned...
Module = type(tst)
class ProtectedModule(Module):
def __setattr__(self, attr, val):
exists = getattr(self, attr, None)
if exists is not None and hasattr(exists, '__assign__'):
exists.__assign__(val)
super().__setattr__(attr, val)
tst.__class__ = ProtectedModule
上面的示例假设代码驻留在一个名为tst
的模块中。您可以在repl
中通过将tst
更改为__main__
来完成此操作。
如果您想通过本地模块保护访问,请通过tst.var = newval
对其进行所有写入。
https://stackoverflow.com/questions/11024646
复制相似问题