【发布时间】:2018-10-31 18:49:30
【问题描述】:
我有一个具有多个属性的类实例:
class MyClass(object):
@property
def func(self):
return [1,4,5]
@property
def func2(self):
return 6
我想从用户提供的新方法中动态更改属性,例如:
obj = MyClass()
def patch_property(name, new_return):
source = '@property\ndef %s(self):\n return %s' % (parameter_name, new_return)
code = compile(source, file_name, 'exec')`
class SubMyClass(MyClass):
eval(code)
obj.__class__ = SubMyClass
patch_property('func', [6,7,8])
这行得通,但是它改变了type(obj),这弄乱了其他一些东西。执行以下操作不会:
cls = type(obj)
new_cls = type(cls.__name__, (cls,), {})
obj.__class__ = new_cls
但是,我无法弄清楚如何在 new_cls 中正确地从上面获取 eval(code)。关于如何解决这个问题的任何想法?
我也尝试过猴子修补属性:
def patch_fun(code):
def patched_fun(self):
eval(code)
return patched_fun
patched_fun = patch_fun(code)
setattr(cls, name, property(patched_fun))
或绑定方法:
patched_fun = patch_fun(code).__get__(obj, type(obj))
setattr(cls, name, property(patched_fun))
(我无法从这些中弄清楚:Dynamically adding a property to a class 、Dynamically adding @property in python、Monkey Patching an attribute within a class、Monkey patching a @property 、Python: changing methods and attributes at runtime
【问题讨论】:
-
compile()在您的代码中似乎存在大规模的安全漏洞。在之前的帖子中尝试过使用 setatrr 和 lambda 函数,感觉更合理。
标签: python python-2.7 class dynamic properties