您现在的位置是:网站首页>文章详情文章详情
Python属性拦截器正确使用及应用场景
inlike2019-05-31【
原创文章
】
浏览(1478)
评论(0)
喜欢(31)
简介属性拦截器__getattribute__,作为Python常用内建属性之一,在实际业务应用场景中有较大作用;但是,这也是一个充满陷阱的方法,不注意就将陷入拦截器制造的死循环中,直到代码奔溃退出,本篇讲解__getattribute__的使用及其一些应用场景。
属性拦截器__getattribute__,作为Python常用内建属性之一,在实际业务应用场景中有较大作用;但是,这也是一个充满陷阱的方法,不注意就将陷入拦截器制造的死循环中,直到代码奔溃退出,本篇讲解__getattribute__的使用及其一些应用场景。
在本博客开发中就遇到这样一个场景:在多级评论功能中,要实现后台可以删除评论,但是在数据库并不真正删除,因为评论之间有着关联关系,一旦删除后将出现多米诺牌效应;因此要实现后台可删除该评论,同时数据库不真正删除,前端显示该评论删除的需求;对于这个问题有不同语言有不同的实现方式,但是使用Python的属性拦截器无疑是最简单的方案。
其基本方案是在定义评论模型的时候,增加一个删除标记字段,当获取评论内容的时候,设置的属性拦截器会先检查删除标记的字段,如果标记删除就返回“该评论已被删除”,如果是未被标记删除的字段就显示正常评论内容。
__getattribute__使用方法:
class Comment(models.Model):
"""评论类"""
topic_id = models.IntegerField(null=True, blank=True) # 文章id
content = models.TextField(verbose_name='评论') # 内容
type = models.IntegerField(default=1, verbose_name='') # 1-文章, 2-公告, 3-留言
from_uid = models.ForeignKey(to='User', to_field='id',
on_delete=models.CASCADE) # 评论用户id
notice = models.BooleanField(default=False, verbose_name='回复通知')
is_top = models.BooleanField(default=False, verbose_name='置顶') # 是否置顶
is_hot = models.BooleanField(default=False, verbose_name='热评') # 是否为热评
like_num = models.IntegerField(default=0, verbose_name='点赞') # 喜欢数
reply_num = models.IntegerField(default=0, verbose_name='回复数') # 回复数
iddelete = models.BooleanField(default=False, verbose_name='删除')
create_time = models.DateTimeField(auto_now_add=True,
verbose_name='时间') # 插入时间
def __getattribute__(self, item):
if item == 'content':
iddelete = self.__dict__.get('iddelete')
if iddelete:
return '该评论已被删除'
else:
return self.__dict__.get('content')
else:
return object.__getattribute__(self, item)
需要注意的是:复写了类自带的拦截器后,对于不在拦截范围的属性要调用自带的object.__getattribute__(self, item)返回正常值,对于我们需要拦截的属性,不能再通过class.name去访问原来的属性值,不然导致死循环,访问本拦截属性的正确方法是通过class.__dict__访问属性字典集合。
通过该方法,我们在访问被拦截属性的时候,就会先对其有效性进行效验,然后按照我们的设定返回值;不得不说属性拦截器在实际业务应用中也有着非常大的价值。
相关文章
本栏推荐

标签云
猜你喜欢
站点信息
- 建站时间:2019-5-24
- 网站程序:like in love
- 主题模板:《今夕何夕》
- 文章统计:104条
- 文章评论:***条
- 微信公众号:扫描二维码,关注我们
