如果要动态创建和引用嵌套属性,最好的方法是什么?
我正在编写一个简单的Flickr客户端,并希望尽可能地匹配所记录的API,而不是实际定义每个方法.例如,要向Flickr的flickr.people.getInfoAPI方法发出请求:
flickr = Client()
data = flickr.people.getInfo(user_id='xxx')
Run Code Online (Sandbox Code Playgroud)
在这种情况下,flickr.people.getInfo直接映射到其API文档中的相应方法.当被调用时,people并且getInfo在查找时创建,然后正确的请求由路径确定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
Run Code Online (Sandbox Code Playgroud)
这是有效的,但我很好奇我是否可以改进处理嵌套属性赋值/查找的方法,或者是否有潜伏等待的错误,我不知道.特别是,我很好奇是否有更好的方法来找出给定属性的"路径".例如,如果我叫Client().x.y.z(),x,y,z不存在,将创建一个由一个(如__getattr__在同一时间抬头单个属性).到时候z叫,我需要能够辨别的路径z是x.y.z.
感谢Thomas K指出flipty已经做到这一点(并且看起来像是一个很好的与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)
Run Code Online (Sandbox Code Playgroud)
Etvoilà:
>>> c = Client()
>>> c.some.method(x=1, y=2)
some.method {'y': 2, 'x': 1}
Run Code Online (Sandbox Code Playgroud)