Как запретить hasattr извлекать само значение атрибута
У меня есть класс, который реализует виртуальные атрибуты, используя __getattr__
, Атрибуты могут быть дорогими, например, выполнение запроса. Теперь я использую библиотеку, которая проверяет, есть ли у моего объекта атрибут перед тем, как его получить.
Как следствие, запрос выполняется два раза вместо одного. Конечно, имеет смысл на самом деле выполнить __getattr__
чтобы действительно знать, если атрибут существует.
class C(object):
def __getattr__(self, name):
print "I was accessed"
return 'ok'
c = C()
hasattr(c, 'hello')
Есть ли способ предотвратить это?
Если Python поддерживается __hasattr__
тогда я мог бы просто проверить, существует ли запрос, против того, чтобы фактически выполнить его.
Я могу создать кеш, но это тяжело, так как запрос может иметь параметры. Конечно, сервер может сам кешировать запросы и минимизировать проблему, но это все еще тяжело, если запросы возвращают много данных.
Есть идеи?
2 ответа
Хотя изначально я не увлекался идеей исправления обезьян, будучи "плохой идеей" в целом, я наткнулся на очень аккуратное решение с 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
По сути это создает поддержку __hasattr__
в Python, который я изначально считал оптимальным решением.
Я думаю, что это, как правило, плохой шаблон, но вы всегда можете проверить основную часть объекта __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