微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 python 中编写描述符 例如:

如何解决在 python 中编写描述符 例如:

背景

在 Python 中,descriptor一个定义 __get____set____delete__,有时也定义 __set_name__ 的对象。 python中最常用的描述符可能是property(getter,setter,deleter,description)属性描述符在调用各自的描述符方法调用给定的 getter、setter 和 deleter。

有趣的是,函数也是描述符:它们定义了 __get__,当被调用时,返回一个绑定方法

描述符用于修改访问对象属性时发生的情况。示例包括限制访问、记录对象访问甚至从数据库动态查找。

问题

我的问题是:如何设计可组合的描述符?

例如:

假设我有一个 Restricted 描述符(仅在满足某种条件时才允许设置和获取)和一个 AccessLog 描述符(每次属性“设置”或“得到”)。我可以设计它们以便在使用它们时组合它们的功能吗?

说我的示例用法如下所示:

class ExampleClient:
  # use them combined,preferably In any order 
  # (and there Could be a special way to combine them,# although functional composition makes the most sense)
  foo: Restricted(AccessLog())
  bar: AccessLog(Restricted())
  # and also use them separately
  qux: Restricted()
  quo: AccessLog()

我正在寻找一种方法将其变成可重用的模式,以便我可以使任何描述符都可组合。关于如何以pythonic方式做到这一点的任何建议?我将自己尝试一些想法,看看什么是有效的,但我想知道是否已经尝试过这种方法,以及是否有某种“最佳实践”或此类事情的通用方法......

解决方法

你可能可以做到这一点。棘手的部分可能是弄清楚如果您的描述符没有要委托给的“子”描述符,那么它们的默认行为应该是什么。也许你想默认行为像一个普通的实例变量?

class DelegateDescriptor:
    def __init__(self,child=None):
        self.child = child
        self.name = None

    def __set_name__(self,owner,name):
        self.name = name
        if self.child is not None:
            try:
                self.child.__set_name__(owner,name)
            except AttributeError:
                pass

    def __get__(self,instance,owner=None):
        if instance is None:
            return self
        if self.child is not None:
            return self.child.__get__(instance,owner)
        try:
            return instance.__dict__[self.name]   # default behavior,lookup the value
        except KeyError:
            raise AttributeError

    def __set__(self,value):
        if self.child is not None:
            self.child.__set__(instance,value)
        else:
            instance.__dict__[self.name] = value  # default behavior,store the value

    def __delete__(self,instance):
        if self.child is not None:
            self.child.__delete__(instance)
        else:
            try:
                del instance.__dict__[self.name]  # default behavior,remove value
            except KeyError:
                raise AttributeError

现在,除了存储值或委托给另一个描述符之外,这个描述符实际上不任何事情。但是,您实际的 RestrictedAccessLog 描述符可能能够将其用作基类,并在顶部添加自己的逻辑。错误检查也非常基础,在生产中使用它之前,您可能希望在每个用例中更好地提出正确类型的异常和适当的错误消息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?