我是一个Python新手,他非常特别地尝试使用Python的点名查找过程。如何编写“make.py”中的类或函数,以便这些赋值语句成功运行?
import make
make.a.dot.separated.name = 666
make.something.else.up = 123
make.anything.i.want = 777
答案 0 :(得分:15)
#!/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
个对象链。这允许点访问被任意深度嵌套,直到最终赋值为此指定实数值。
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)
。