是否有可能超载Python分配?
是否有一个神奇的方法,可以重载赋值运算符,如__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() 
可能吗? 疯了吗? 我应该吃药吗?
你描述的方式是绝对不可能的。 赋值给一个名字是Python的一个基本特征,并没有提供任何钩子来改变它的行为。
 但是,通过覆盖.__setattr__() , 可以根据需要控制对类实例中成员的赋值。 
 class MyClass(object): def __init__(self, x): self.x = x self._locked = True def __setattr__(self, name, value): if self.__dict__.get("_locked") and name == "x": raise AttributeError, "MyClass does not allow assignment to .x member" self.__dict__[name] = value >>> m = MyClass(3) >>> mx 3 >>> mx = 4 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 7, in __setattr__ AttributeError: MyClass does not allow assignment to .x member 
 请注意,有一个成员variables_locked ,用于控制赋值是否被允许。 你可以解锁它来更新值。 
不,因为作业是一种没有修改钩子的语言内在 。
我不认为这是可能的。 我看到它的方式,赋值给一个variables不会对之前提到的对象做任何事情:只是variables“指向”一个不同的对象。
 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__()方法创build包装对象来模仿所需的行为,从而引发exception,并将“不可更改”的内容保留在内部。 
没有没有
考虑一下,在你的例子中,你正在重新命名var为一个新的值。 你实际上并没有触及Protect的实例。
如果您希望重新绑定的名称实际上是某个其他实体的属性,即myobj.var,那么您可以防止为该实体的属性/属性分配一个值。 但是我认为这不是你想要的。
 在全局命名空间中,这是不可能的,但是您可以利用更高级的Python元编程来防止创buildProtect对象的多个实例。  Singleton模式就是一个很好的例子。 
在Singleton的情况下,您可以确保一旦实例化,即使引用实例的原始variables被重新分配,该对象也会保留。 任何后续的实例只会返回对同一个对象的引用。
尽pipe这种模式,你永远不能防止全球variables名称被重新分配。
使用顶级命名空间,这是不可能的。 当你跑步
 `var = 1` 
 它将关键字var和值1在全局字典中。 这大致相当于调用globals().__setitem__('var', 1) 。 问题是你不能在一个正在运行的脚本中replace全局字典(你可能可以通过乱搞堆栈,但这不是一个好主意)。 但是,您可以在辅助命名空间中执行代码,并为其全局提供自定义字典。 
 class myglobals(dict): def __setitem__(self, key, value): if key=='val': raise TypeError() dict.__setitem__(self, key, value) myg = myglobals() dict.__setitem__(myg, 'val', 'protected') import code code.InteractiveConsole(locals=myg).interact() 
 这将触发一个几乎正常运行的REPL,但拒绝尝试设置variablesval 。 你也可以使用execfile(filename, myg) 。 请注意,这不能防止恶意代码。 
一个丑陋的解决scheme是重新分配的析构函数。 但这不是真正的超载分配。
 import copy global a class MyClass(): def __init__(self): a = 1000 # ... def __del__(self): a = copy.copy(self) a = MyClass() a = 1 
 是的,这是可能的,你可以通过修改ast处理__assign__ 。 
 pip install assign 
testing:
 class T(): def __assign__(self, v): print('called with %s' % v) b = T() c = b 
你会得到
 >>> import magic >>> import test called with c 
 该项目是在https://github.com/RyanKung/assign更简单的要点: https://gist.github.com/RyanKung/4830d6c8474e6bcefa4edd13f122b4df : https://gist.github.com/RyanKung/4830d6c8474e6bcefa4edd13f122b4df