如何将函数中不变逻辑迁移至其他项目?装饰器实现方案探讨
解决方案:用装饰器抽离通用逻辑
完全可以用装饰器实现需求,把和Counter交互的通用逻辑封装成装饰器,业务类里只需要保留随项目变化的专属代码。
1. 编写通用装饰器
这个装饰器会自动处理所有和Counter交互的重复逻辑,代码如下:
def counter_decorator(func): def wrapper(self, n=1): # 先执行业务专属代码 func(self, n) # 执行通用的Counter交互逻辑 self.counter.counter_foo(n) if self.status == 'On': self.counter.set_status(self.status) return wrapper
2. 修改业务类First
给需要应用通用逻辑的方法加上装饰器,此时业务方法只保留核心代码:
class Counter(object): def __init__(self): self.foo = 0 self.status = 'Off' def counter_foo(self, n): self.foo += n def set_status(self, status): self.status = status class First(object): def __init__(self): self.counter = Counter() self.status = 'On' @counter_decorator def print_foo(self, n=1): print('foo' * n) # 其他5个类似函数,只需要加@counter_decorator装饰器即可 @counter_decorator def another_func(self, n=2): print('bar' * n) def main(): foobar = First() foobar.print_foo(8) # 验证功能:counter的foo会变成8,status会被设为On print(foobar.counter.foo) print(foobar.counter.status)
3. 装饰器如何访问实例属性?
装饰器的wrapper函数第一个参数是self,这就是方法所属的实例对象(比如示例中的foobar)。通过这个self可以直接访问实例的所有属性:
- 用
self.counter拿到Counter类的实例,调用它的counter_foo和set_status方法 - 用
self.status获取实例的状态值,判断是否需要更新Counter的状态
扩展说明
如果实际项目中有多个这类函数,只需要给每个函数加上@counter_decorator装饰器即可,无需重复编写通用逻辑。后续如果通用逻辑需要调整,只修改装饰器一处就能同步更新所有相关方法的逻辑,大幅提升代码维护性。
内容的提问来源于stack exchange,提问作者LiverLove
相关产品推荐
相关产品推荐

