首页 > 解决方案 > 如何实现虚拟属性层次结构?

问题描述

是否可以创建一个支持以下内容的 Python 对象?

obj = ...
obj.abc.def = 123
print(obj.abc.def)
x = obj.abc.ghi(1,2,3)

关键是它obj不应该包含所有属性(可能很多,并且可能事先不知道),而是以调用某种处理程序结束,例如handler(obj,'get','abc','def'),等等,以执行请求的操作并返回其结果。

我所追求的是一种方便的交互式使用符号,使用点符号来访问对象的特定细节,而不使用对象的对象的对象。

我理解__getattr__and __setattr__,并且我已经阅读了Python 3 中的描述符,也许我应该考虑制作__dict__一个映射对象,但是当面对a.b.c样式子属性时,我在涉及的开放式嵌套上遇到了冲突。

标签: python

解决方案


可以使用defaultdict以下方式定义树结构:

from collections import defaultdict

def tree():
    return defaultdict(tree)

这可用于动态创建任意嵌套的键:

t = tree()
t['a']['b']['c'] = 123

使用属性访问,我们可以使用__getattr____setattr__委托对类似递归形式的底层 dict 的调用:

class Tree:
    def __init__(self):
        super().__setattr__('t', defaultdict(Tree))

    def __getattr__(self, name):
        return self.t[name]

    def __setattr__(self, name, value):
        self.t[name] = value

现在可以通过访问属性来动态生成属性:

t = Tree()
t.a.b.c = 123

推荐阅读