如何处理Python查找:make.up.a.dot.separated.name.and.use.it.until.destroyed = 777

6

我是一个Python新手,非常想尝试使用Python的点名称查找过程。 我该如何在“make.py”中编写类或函数,以便这些赋值语句成功工作?

import make

make.a.dot.separated.name = 666
make.something.else.up = 123
make.anything.i.want = 777
1个回答

20
#!/usr/bin/env python

class Make:
    def __getattr__(self, name):
        self.__dict__[name] = Make()
        return self.__dict__[name]

make = Make()

make.a.dot.separated.name = 666
make.anything.i.want = 777

print make.a.dot.separated.name
print make.anything.i.want

特殊的__getattr__方法在找不到命名值时被调用。行make.anything.i.want最终相当于以下代码:
m1 = make.anything    # calls make.__getattr__("anything")
m2 = m1.i             # calls m1.__getattr__("i")
m2.want = 777

上述实现使用这些调用__getattr__来创建一个Make对象链,每次访问未知属性时。这允许点访问任意深度的嵌套,直到最终赋值为止,此时将分配一个真实值。

Python文档 - 自定义属性访问

object.__getattr__(self, name)

当属性查找在通常的位置(即不是实例属性,也没有在self的类树中找到)中未找到属性时调用。 name 是属性名称。此方法应返回(计算的)属性值或引发AttributeError异常。

请注意,如果通过正常机制找到属性,则不会调用__getattr __()。(这是__getattr__() __setattr__() 之间有意的不对称性。)这样做既是出于效率原因,也是因为否则__getattr__()将无法访问实例的其他属性。 请注意,至少对于实例变量,您可以通过不在实例属性字典中插入任何值(而是将它们插入另一个对象中)来模拟总控制。有关在新式类中实际获得总控制的方法,请参见下面的__getattribute__()方法。

object.__setattr__(self, name, value)

尝试进行属性赋值时调用。这是代替正常机制(即将值存储在实例字典中)调用的。 name是属性名称,value是要分配给它的值。

如果__setattr__()想要分配给实例属性,则不应简单地执行self.name = value - 这将导致递归调用自身。相反,它应该将值插入到实例属性字典中,例如,self.__dict__[name] = value。对于新式类,它应该调用具有相同名称的基类方法,例如,object.__setattr__(self, name, value),而不是访问实例字典。


有没有地方可以阅读dict属性以及此代码示例的工作方式? - Geo
@John Kugelman,我对你的回答的简洁优雅之美感到惊叹。非常漂亮。 - steveha
@blindvic,Python允许简洁优美的简单性,但并不保证它!正如老话所说:“真正的程序员可以用任何语言编写FORTRAN。” - steveha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接