Python类方法装饰器如何获取self以实现数据库连接自动开闭
类方法装饰器获取self实例的解决方案
实例方法被调用时,第一个传入的位置参数就是实例本身self,直接从wrapper的可变位置参数args的首位提取即可。
修改后的装饰器代码
def make_connection(func): def wrapper(*args, **kwargs): # 提取首位参数即为实例self self = args[0] self.open_connection() # 执行原方法逻辑 r = func(*args, **kwargs) self.close_connection() return r return wrapper
改造后的MyDB类代码
class MyDB(): def __init__(self, value): self.value = value def open_connection(self): print ("open connection for "+self.value) def close_connection(self): print ("close connection "+self.value) @make_connection def doA(self, request): print ("DO A "+request) @make_connection def doB(self): print ("DO B")
验证结果
执行原有调用代码:
db = MyDB('remote') db.doA(request='ABC')
输出结果和原有实现完全一致:
open connection for remote DO A ABC close connection remote
兼容校验(可选)
如果需要避免装饰器被错误应用到非实例方法场景,可以增加参数和属性校验:
def make_connection(func): def wrapper(*args, **kwargs): # 校验是否存在首位实例参数 if not args: raise TypeError("该装饰器仅可用于类实例方法") self = args[0] # 校验实例是否包含所需的连接方法 if not all(hasattr(self, method) for method in ["open_connection", "close_connection"]): raise AttributeError("当前实例缺少连接开闭的必要方法") self.open_connection() r = func(*args, **kwargs) self.close_connection() return r return wrapper
内容的提问来源于stack exchange,提问作者ProcolHarum
相关产品推荐
相关产品推荐

