如何自定义兼具属性校验的Python装饰器以替代@property组合使用?
解决方案:整合属性检查与Property转换的自定义装饰器
这个问题其实很好解决——我们只需要把属性检查逻辑和property的创建流程整合到同一个装饰器里,就能省去每次同时写两个装饰器的麻烦。
核心思路
@property本质上是一个类,它的实例会把被装饰的方法转化为属性的getter。所以我们的自定义装饰器只需要:
- 先给原方法套上属性检查的逻辑
- 把包装后的函数作为getter传入
property类,返回这个property实例即可
完整实现代码
def my_new_decorator(f): def getter(self): # 执行前置属性检查 if self.my_attribute is None: raise ValueError('No location set to model.') # 调用原方法并返回结果 return f(self) # 返回property对象,将包装后的函数作为getter return property(getter) class MyClass: my_attribute = None @my_new_decorator def my_method(self): return self.my_attribute
测试验证
我们可以简单测试一下这个装饰器的效果:
# 初始化实例 obj = MyClass() # 当my_attribute为None时,访问属性会触发检查报错 try: print(obj.my_method) except ValueError as e: print(e) # 输出: No location set to model. # 设置属性后,正常返回结果 obj.my_attribute = "Hello Property!" print(obj.my_method) # 输出: Hello Property!
扩展说明(可选)
如果之后你需要支持property的setter或deleter逻辑,可以给装饰器添加扩展功能,比如:
def my_new_decorator(f=None, setter=None): def decorator(func): def getter(self): if self.my_attribute is None: raise ValueError('No location set to model.') return func(self) prop = property(getter) # 如果传入了setter函数,绑定到property的setter if setter is not None: prop = prop.setter(setter) return prop # 处理装饰器带参数的情况 if f is None: return decorator return decorator(f)
这样你就可以灵活地给属性添加setter逻辑了。
内容的提问来源于stack exchange,提问作者user144153
相关产品推荐
相关产品推荐

