我有一个使用__getattr__
实现虚拟属性的类。属性可能很昂贵,例如执行查询。现在,我正在使用一个库,在实际获取之前检查我的对象是否具有该属性。
因此,查询将执行两次而不是一次。当然,实际执行__getattr__
以确定属性是否存在是有意义的。
class C(object):
def __getattr__(self, name):
print "I was accessed"
return 'ok'
c = C()
hasattr(c, 'hello')
有什么方法可以阻止这种情况吗?
如果Python支持__hasattr__
,那么我可以简单地检查查询是否存在,反对实际运行它。
我可以创建一个缓存,但它很重,因为查询可能有参数。当然,服务器可能会缓存查询本身并最小化问题,但如果查询返回大量数据,它仍然很重。
有什么想法吗?
答案 0 :(得分:3)
虽然最初我并不喜欢猴子修补的想法,但这是一个“坏主意”#34;总的来说,我从1999年开始就遇到了一个非常简洁的解决方案!!
http://code.activestate.com/lists/python-list/14972/
def hasattr(o, a, orig_hasattr=hasattr):
if orig_hasattr(o, "__hasattr__"):
return o.__hasattr__(a)
return orig_hasattr(o, a)
__builtins__.hasattr = hasattr
基本上它在Python中创建了对__hasattr__
的支持,这是我认为最初的解决方案。
答案 1 :(得分:0)
我认为这通常可能是一种糟糕的模式,但您始终可以检查对象的基础__dict__
。
In [1]: class A(object):
....: @property
....: def wha(self):
....: print "was accessed"
....:
In [2]: A.__dict__
Out[2]:
<dictproxy {'__dict__': <attribute '__dict__' of 'A' objects>,
'__doc__': None,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'A' objects>,
'wha': <property at 0x10f6b11b0>}>
In [3]: a = A()
In [4]: "wha" in a.__class__.__dict__
Out[4]: True