6

我是一个 Python 新手,非常渴望尝试 Python 的点名查找过程。如何在“make.py”中对类或函数进行编码,以使这些赋值语句成功运行?

import make

make.a.dot.separated.name = 666
make.something.else.up = 123
make.anything.i.want = 777
4

1 回答 1

19
#!/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).

于 2009-10-21T18:55:25.450 回答