当前位置: 首页 > 面试题库 >

描述符作为python中的实例属性

岑炯
2023-03-14
问题内容

描述符对象需要存在于类中,而不是存在于实例中

因为那是实现的方式__getattribute__

一个简单的例子。考虑一个描述符:

class Prop(object):

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        return obj._value * obj._multiplier

    def __set__(self, obj, value):
        if obj is None:
            return self
        obj._value = value

class Obj(object):

    val = Prop()

    def __init__(self):
        self._value = 1
        self._multiplier = 0

考虑每个obj具有多个Prop的情况:我将需要使用唯一的名称来标识值和乘数(如此处。具有每个实例的描述符对象将允许将_multiplier(和_value)存储在描述符本身中,从而简化了几样东西。

我知道以前也曾提出过类似的问题,但我没有找到真正的解释:

  1. 为什么以这种方式设计Python?
  2. 建议使用哪种方式存储描述符需要的信息,但按实例存储?

问题答案:

只有在类而不是实例上定义时,大量高级功能才起作用。例如,所有特殊方法。除了使代码评估更有效之外,这还使实例和类型之间的分隔变得清晰,否则分隔将容易崩溃(因为所有类型都是对象)。

我不确定这是如何推荐的,但是您可以在实例中存储从描述符实例到属性值的映射:

class Prop(object):
     def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        return obj._value * obj._multiplier[self]

    def __set__(self, obj, value):
        if obj is None:
            return self
        obj._value = value

class Obj(object):
    val = Prop()

    def __init__(self):
        self._value = 1
        self._multiplier = {Obj.val: 0}

与其他两个建议的选项相比,它具有明显的优势:

  1. 每个实例的类破坏了面向对象并增加了内存使用;
  2. 覆盖__getattribute__是低效的(因为所有属性访问都必须通过覆盖的特殊方法进行访问)并且脆弱。

或者,您可以使用proxy属性:

class PerInstancePropertyProxy(object):
    def __init__(self, prop):
        self.prop = prop
    def __get__(self, instance, owner):
        if instance is None:
            return self
        return instance.__dict__[self.prop].__get__(instance, owner)
    def __set__(self, instance, value):
        instance.__dict__[self.prop].__set__(instance, value)
class Prop(object):
    def __init__(self, value, multiplier):
        self.value = value
        self.multiplier = multiplier
    def __get__(self, instance, owner):
        if instance is None:
            return self
        return self.value * self.multiplier
    def __set__(self, instance, value):
        self.value = value
class Obj(object):
    val = PerInstancePropertyProxy('val')
    def __init__(self):
        self.__dict__['val'] = Prop(1.0, 10.0)
    def prop(self, attr_name):
        return self.__dict__[attr_name]


 类似资料:
  • 本文向大家介绍通过实例解析python描述符原理作用,包括了通过实例解析python描述符原理作用的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了通过实例解析python描述符原理作用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 本质上看,描述符是一个类,只不过它定义了另一个类中属性的访问方式。换句话说,一个类可以将属性管理全权委托

  • 问题内容: 当我将“数据”变量设为类变量时,以下工作有效,但是当我将其变为对象变量时,则不会调用描述符。请帮忙。 问题答案: 这是因为描述符仅应定义为类属性,而不是实例属性: 从文档: 以下方法仅在包含该方法的类的实例(所谓的描述符类)出现在所有者类中( 描述符必须位于所有者的类字典或父类的父类的类字典中 )时适用。 为了使描述符也能与实例属性一起使用,您需要重写。方法(尚未进行全面测试,但可以根

  • Python 中,通过使用描述符,可以让程序员在引用一个对象属性时自定义要完成的工作。 本质上看,描述符就是一个类,只不过它定义了另一个类中属性的访问方式。换句话说,一个类可以将属性管理全权委托给描述符类。 描述符是 Python 中复杂属性访问的基础,它在内部被用于实现 property、方法、类方法、静态方法和 super 类型。 描述符类基于以下 3 个特殊方法,换句话说,这 3 个方法组成

  • 本文向大家介绍解密Python中的描述符(descriptor),包括了解密Python中的描述符(descriptor)的使用技巧和注意事项,需要的朋友参考一下 Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解。这些特性包括列表/集合/字典推导式,属性(property)、以及装饰器(decorator)。对于大部分特性来说,这些“中级”的语言特性有着完善的文档,并且易于学习。

  • 我们知道,对象可以存储属性。 到目前为止,属性对我们来说只是一个简单的“键值”对。但对象属性实际上是更灵活且更强大的东西。 在本章中,我们将学习其他配置选项,在下一章中,我们将学习如何将它们无形地转换为 getter/setter 函数。 属性标志 对象属性(properties),除 value 外,还有三个特殊的特性(attributes),也就是所谓的“标志”: writable — 如果为

  • 以下示例是注册两个 Servlet 上下文生命周期监听器和一个HttpSession 监听器的部署语法。 假设 com.acme.MyConnectionManager 和 com.acme.MyLoggingModule两个都实现了 javax.servlet.ServletContextListener,且com.acme.MyLoggingModule 又实现了javax.servlet.h