包装获取和设置属性方法而不编辑原始 Class
Wrap get and set attributes methods without editing original Class
我正在尝试在 属性 设置 or/and 之前或之后执行一些操作。
这段代码棘手的部分是我不能修改原来的 class.
class 的方法没有问题,它按预期工作。但是我找不到处理属性的方法。我有一个错误:
TypeError: readonly attribute
如果有人可以帮助我找到正确的方向......
这是Class我不能修改的:
class Test(object):
def __init__(self):
super(Test, self).__init__()
self._param = None
self._controler = None
self._message = None
@property
def param(self):
return self._param
@param.setter
def param(self, param):
self._param = param
@property
def controler(self):
return self._controler
def message(self):
print('message')
这是我为完成这项工作而编写的包装器,它将成为我模块的一部分
def add_things_before_and_after(function_to_enhance):
def new_wrapper(self):
print("Before function execution")
function_to_enhance(self)
print("After function execution")
return new_wrapper
这是为使用包装器和实例化 class
而编写的代码
# this one works as expected
Test.message = add_things_before_and_after(Test.message)
# these two lines does not work
Test.param.fget = add_things_before_and_after(Test.param.fget)
Test.controler.fget = add_things_before_and_after(Test.controler.fget)
test = Test()
test.message()
test.param = 1
print(test.param)
print(test.controler)
这可以通过用新的覆盖整个 param
属性 来实现。但是,您的装饰器函数必须固定为 return 包装函数的值。
functools.wraps
是保留包装函数的属性(名称、文档等)的好方法。
from functools import wraps
def add_things_before_and_after(function_to_enhance):
@wraps(function_to_enhance)
def new_wrapper(self):
print("Before function execution")
r = function_to_enhance(self)
print("After function execution")
return r
return new_wrapper
# this one works as expected
Test.message = add_things_before_and_after(Test.message)
# these two lines should work
Test.param = property(add_things_before_and_after(Test.param.fget), Test.param.fset)
Test.controler = property(add_things_before_and_after(Test.controler.fget), Test.controler.fset)
test = Test()
test.message()
test.param = 1
print(test.param)
print(test.controler)
# ==Output==
#
# Before function execution
# message
# After function execution
# Before function execution
# After function execution
# 1
# Before function execution
# After function execution
# None
我正在尝试在 属性 设置 or/and 之前或之后执行一些操作。 这段代码棘手的部分是我不能修改原来的 class.
class 的方法没有问题,它按预期工作。但是我找不到处理属性的方法。我有一个错误:
TypeError: readonly attribute
如果有人可以帮助我找到正确的方向......
这是Class我不能修改的:
class Test(object):
def __init__(self):
super(Test, self).__init__()
self._param = None
self._controler = None
self._message = None
@property
def param(self):
return self._param
@param.setter
def param(self, param):
self._param = param
@property
def controler(self):
return self._controler
def message(self):
print('message')
这是我为完成这项工作而编写的包装器,它将成为我模块的一部分
def add_things_before_and_after(function_to_enhance):
def new_wrapper(self):
print("Before function execution")
function_to_enhance(self)
print("After function execution")
return new_wrapper
这是为使用包装器和实例化 class
而编写的代码# this one works as expected
Test.message = add_things_before_and_after(Test.message)
# these two lines does not work
Test.param.fget = add_things_before_and_after(Test.param.fget)
Test.controler.fget = add_things_before_and_after(Test.controler.fget)
test = Test()
test.message()
test.param = 1
print(test.param)
print(test.controler)
这可以通过用新的覆盖整个 param
属性 来实现。但是,您的装饰器函数必须固定为 return 包装函数的值。
functools.wraps
是保留包装函数的属性(名称、文档等)的好方法。
from functools import wraps
def add_things_before_and_after(function_to_enhance):
@wraps(function_to_enhance)
def new_wrapper(self):
print("Before function execution")
r = function_to_enhance(self)
print("After function execution")
return r
return new_wrapper
# this one works as expected
Test.message = add_things_before_and_after(Test.message)
# these two lines should work
Test.param = property(add_things_before_and_after(Test.param.fget), Test.param.fset)
Test.controler = property(add_things_before_and_after(Test.controler.fget), Test.controler.fset)
test = Test()
test.message()
test.param = 1
print(test.param)
print(test.controler)
# ==Output==
#
# Before function execution
# message
# After function execution
# Before function execution
# After function execution
# 1
# Before function execution
# After function execution
# None