У меня есть экземпляр класса с несколькими свойствами:
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
Однако я не могу понять, как правильно получить eval(code)
сверху в new_cls.Любые идеи о том, как решить эту проблему?
Я также пытался установить свойство обезьяны:
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))
(я не мог понятьэто из этих: Динамическое добавление свойства в класс , Динамическое добавление @property в python , Обезьяна Исправление атрибута в классе , Обезьянаисправление Python @property , : изменение методов и атрибутов во время выполнения