在类内部创建decorator作为方法会导致self错误



我正在尝试在类内部创建decorator,并且需要访问decorator 内部的self

这是我的代码

import functools
class Rtest(object):
def __init__(self, *args, **kwargs):
self.key1 = "foo"
self.value1 = "bar"

def continue_exception(self, func, **kwargs):
@functools.wraps(func)
def inner_function(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
import traceback
print(f"Error with {kwargs.get('key')} :  {kwargs.get('value')}")
print(f"Exception {traceback.format_exc()}")
return
return inner_function
def add1(self, n1, n2):
return n1 + n2
@continue_exception(key=self.key1, value=self.value1)
def add2(self, n1, n2):
return n1 + n2

obj = Rtest()
print(obj.add1(4,5))
print(obj.add2("fdfd", 6))

我收到这个错误

@continue_exception(key="foo", value="bar")

TypeError:continue_exception((缺少2个必需的位置参数:"self"one_answers"func">

您的程序存在以下问题:

  1. 装饰器函数的定义有问题。当它在@continue_exception(key="foo", value="bar")中使用时,没有func参数,它只会接收您传入的位置参数。因为此时它是先执行的,然后执行装饰功能。

  2. continue_exception是一个实例方法,除非你能把一个对象传递给它,否则你不能把它用作装饰器。所以你可以把它变成一个静态方法,是的,你可以,因为self没有在函数内部使用。

以下代码修复了上述问题并成功运行。

import functools
class Rtest(object):
def __init__(self, *args, **kwargs):
self.key1 = "foo"
self.value1 = "bar"

@staticmethod
def continue_exception(**kwargs):
def wrapper(func):
@functools.wraps(func)
def inner_function(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
import traceback
print(f"Error with {kwargs.get('key')} :  {kwargs.get('value')}")
print(f"Exception {traceback.format_exc()}")
return
return inner_function
return wrapper
def add1(self, n1, n2):
return n1 + n2
@continue_exception(key="foo", value="bar")
def add2(self, n1, n2):
return n1 + n2

obj = Rtest()
print(obj.add1(4,5))
print(obj.add2("fdfd", 6))

输出:

9
Error with None :  None
Exception Traceback (most recent call last):
File "/home/wujun/Projects/code_test/test.py", line 15, in inner_function
return func(*args, **kwargs)
File "/home/wujun/Projects/code_test/test.py", line 29, in add2
return n1 + n2
TypeError: can only concatenate str (not "int") to str
None

如果要实时获取key1value1的值,可以进行以下修改。

import functools
class Rtest(object):
def __init__(self, *args, **kwargs):
self.key1 = "foo"
self.value1 = "bar"

@staticmethod
def continue_exception(func):
@functools.wraps(func)
def inner_function(*args, **kwargs):
self, *_ = args
try:
return func(*args, **kwargs)
except Exception as e:
import traceback
print(f"Error with {self.key1} :  {self.value1}")
print(f"Exception {traceback.format_exc()}")
return
return inner_function
def add1(self, n1, n2):
return n1 + n2
@continue_exception
def add2(self, n1, n2):
return n1 + n2

obj = Rtest()
print(obj.add1(4,5))
print(obj.add2("fdfd", 6))

相关内容

  • 没有找到相关文章

最新更新