Как запретить 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
Другие вопросы по тегам