【发布时间】:2015-07-29 04:49:52
【问题描述】:
我有一个使用__getattr__ 实现虚拟属性的类。属性可能很昂贵,例如执行查询。现在,我正在使用一个库,它会在实际获取对象之前检查我的对象是否具有该属性。
因此,一个查询被执行了两次而不是一次。当然,实际执行__getattr__ 以真正知道该属性是否存在是有意义的。
class C(object):
def __getattr__(self, name):
print "I was accessed"
return 'ok'
c = C()
hasattr(c, 'hello')
有什么办法可以防止这种情况发生吗?
如果 Python 支持 __hasattr__,那么我可以简单地检查查询是否存在,而不是实际运行它。
我可以创建一个缓存,但它很重,因为查询可能有参数。当然,服务器可能会自己缓存查询并将问题最小化,但如果查询返回大量数据,它仍然很重。
有什么想法吗?
【问题讨论】:
-
如果我理解的情况正确,您只需要基于
name进行缓存,所以这可能只是一个字典。 BTW,你为什么要让它看起来像一个属性? -
如果对象不支持查询,你希望发生什么?
-
hasattr不是属性的轻量级测试;它调用getattr本质上类似于try: getattr('name'); except AttributeError: return False; else: return True。 -
我认为除了猴子补丁
hasattr之外,没有其他方法可以做你想做的事,不推荐这样做。如果没有办法避免调用hasattr,我相信您唯一的选择是缓存结果或允许查询运行两次。 -
@shashank,如果查询不可用(按名称),则返回未找到属性的异常。