You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python描述符__get__方法代码解析:含义、原理及替代方案

关于Python描述符__get__方法的解析与替代方案

一、__get__方法的基本作用

这段代码是描述符协议中的__get__方法:当你通过实例访问绑定了描述符的属性时(比如obj.my_attr),Python会自动调用该方法;如果通过类访问(比如MyClass.my_attr),instance参数会是None,owner参数始终是属性所属的类。

二、instance.__dict__.get(self.name)的作用拆解

  1. instance.__dict__:每个Python实例都自带一个__dict__字典,专门存储该实例独有的属性(和类属性区分开)。比如你给obj.x = 10赋值,x就会被存在obj.__dict__里。

  2. self.name:这是描述符实例自身的属性,通常是在描述符绑定到类属性时自动设置的(比如Python 3.6+的__set_name__方法),对应它在类中的属性名。例如:

    class MyClass:
        my_attr = MyDescriptor()  # 此时MyDescriptor实例的self.name会被设为'my_attr'
    
  3. .get(self.name):从实例的__dict__字典中取出self.name对应的属性值,如果这个属性不存在,就返回None(不会像直接用[]索引那样抛出KeyError)。

    为什么不用getattr(instance, self.name)?因为getattr会再次触发描述符的__get__方法,导致无限递归——毕竟你就是在__get__里调用它,等于自己调用自己死循环。

三、替代实现方式

1. 用底层属性获取方法避免递归

如果不想直接操作__dict__,可以用object.__getattribute__——这是Python最底层的属性获取方法,不会触发描述符协议:

def __get__(self, instance, owner=None):
    print(f'__get__(instance={instance}, owner={owner})')
    try:
        return object.__getattribute__(instance, self.name)
    except AttributeError:
        return None

这段代码和原逻辑效果一致:属性不存在时返回None;如果不需要处理不存在的情况,直接去掉try-except即可,此时属性不存在会抛出AttributeError。

2. 将值存储在描述符内部(适合代理/隔离场景)

如果不想把属性值存在实例的__dict__里,可以用WeakKeyDictionary存储每个实例对应的值,既不会污染实例的__dict__,还能避免内存泄漏:

from weakref import WeakKeyDictionary

class MyDescriptor:
    def __init__(self):
        self._instance_values = WeakKeyDictionary()

    def __set_name__(self, owner, name):
        self.name = name

    def __get__(self, instance, owner=None):
        print(f'__get__(instance={instance}, owner={owner})')
        if instance is None:
            return self  # 类访问时返回描述符自身
        return self._instance_values.get(instance)

    def __set__(self, instance, value):
        self._instance_values[instance] = value

这种方式下,每个实例的属性值都存在描述符的_instance_values字典里,通过实例作为键关联对应的值。


内容的提问来源于stack exchange,提问作者madhur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 23:40:31