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

Moc*_*Why 5 python lookup namespaces

我是一个Python新手,非常特别地尝试Python的点名查找过程.如何编写"make.py"中的类或函数,以便这些赋值语句成功运行?

import make

make.a.dot.separated.name = 666
make.something.else.up = 123
make.anything.i.want = 777
Run Code Online (Sandbox Code Playgroud)

Joh*_*ica 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
Run Code Online (Sandbox Code Playgroud)

__getattr__未找到命名值时调用特殊方法.该行make.anything.i.want最终做了相当于:

m1 = make.anything    # calls make.__getattr__("anything")
m2 = m1.i             # calls m1.__getattr__("i")
m2.want = 777
Run Code Online (Sandbox Code Playgroud)

上述实现使用这些调用在每次访问未知属性时__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).


编辑:旧的,更复杂的答案.实现__getattr__是不必要的.

#!/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
Run Code Online (Sandbox Code Playgroud)