您现在的位置是:网站首页>文章详情文章详情

Python属性拦截器正确使用及应用场景

inlike2019-05-31 原创文章 浏览(1981) 评论(0) 喜欢(34)

简介属性拦截器__getattribute__,作为Python常用内建属性之一,在实际业务应用场景中有较大作用;但是,这也是一个充满陷阱的方法,不注意就将陷入拦截器制造的死循环中,直到代码奔溃退出,本篇讲解__getattribute__的使用及其一些应用场景。

属性拦截器__getattribute__,作为Python常用内建属性之一,在实际业务应用场景中有较大作用;但是,这也是一个充满陷阱的方法,不注意就将陷入拦截器制造的死循环中,直到代码奔溃退出,本篇讲解__getattribute__的使用及其一些应用场景。

image.png

在本博客开发中就遇到这样一个场景:在多级评论功能中,要实现后台可以删除评论,但是在数据库并不真正删除,因为评论之间有着关联关系,一旦删除后将出现多米诺牌效应;因此要实现后台可删除该评论,同时数据库不真正删除,前端显示该评论删除的需求;对于这个问题有不同语言有不同的实现方式,但是使用Python的属性拦截器无疑是最简单的方案。

image.png

其基本方案是在定义评论模型的时候,增加一个删除标记字段,当获取评论内容的时候,设置的属性拦截器会先检查删除标记的字段,如果标记删除就返回“该评论已被删除”,如果是未被标记删除的字段就显示正常评论内容。

__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__访问属性字典集合。

image.png

通过该方法,我们在访问被拦截属性的时候,就会先对其有效性进行效验,然后按照我们的设定返回值;不得不说属性拦截器在实际业务应用中也有着非常大的价值。

很赞哦! ( 34)
    《Python实战进阶》
    None
    None
    夏至已深

站点信息

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