15

如果要动态创建和引用嵌套属性,最好的方法是什么?

我正在编写一个简单的 Flickr 客户端,并希望尽可能地匹配记录在案的 API,而无需实际定义每个方法。例如,向 Flickr 的flickr.people.getInfoAPI 方法发出请求:

flickr = Client()
data = flickr.people.getInfo(user_id='xxx')

在这种情况下flickr.people.getInfo,直接映射到其 API 文档中的相应方法。当调用peoplegetInfo在查找时创建它们时,发出的正确请求由 的路径决定getInfo,即people.getInfo. 这是我使用的方法:

class Attr(object):
    def __init__(self, client, name, parent):
        self._client = client
        self._name = name
        self._parent = parent

    def __getattr__(self, name):
        attr = Attr(self._client, name, self)
        setattr(self, name, attr)
        return attr

    def _get_path(self, path=None):
        if path:
            path = '.'.join((self._name, path))
        else:
            path = self._name
        if isinstance(self._parent, Attr):
            return self._parent._get_path(path)
        return path

    def __call__(self, *args, **kwargs):
        return self._client.execute_method(self._get_path(), *args, **kwargs)

class Client(object):
    def __getattr__(self, name):
        attr = Attr(self, name, None)
        setattr(self, name, attr)
        return attr

    def execute_method(self, method, *args, **kwargs):
        print method, args, kwargs

这行得通,但我很好奇我处理嵌套属性分配/查找的方法是否可以改进,或者是否有任何错误潜伏在等待中,我不知道。特别是,我很好奇是否有更好的方法来找出给定属性的“路径”。例如,如果我调用Client().x.y.z(), x, y,z不存在,并且会被一个一个地创建(因为一次__getattr__查找一个属性)。到时间z被调用时,我需要能够辨别到的路径zx.y.z

4

1 回答 1

7

感谢Thomas K指出Flipy已经做到了这一点(并且似乎是一个与 flickr 交互的好库)。更清洁的方法:

class Method(object):
    def __init__(self, client, method_name):
        self.client = client
        self.method_name = method_name

    def __getattr__(self, key):
        return Method(self.client, '.'.join((self.method_name, key)))

    def __call__(self, **kwargs):
        print self.method_name, kwargs

class Client(object):
    def __getattr__(self, key):
        return Method(self, key)

等等:

>>> c = Client()  
>>> c.some.method(x=1, y=2)
some.method {'y': 2, 'x': 1}
于 2011-06-28T00:18:06.367 回答