Проверка наличия у объекта атрибута, не полагаясь на '__getattr__'
Есть ли способ проверить, есть ли у объекта атрибут, который не зависит от __getattr__
или особенности реализации объекта?
Рассмотрим код ниже. я хочуProxy
делегировать Wrapped
с чем он не может справиться. Код работает, но я бы не хотел тестироватьattr in self.__dict__
(Я бы предпочел для этого стабильный интерфейс, без использования причуд реализации). Функцияhasattr
здесь не помогает, потому что он направляется к обернутому объекту через __getattr__
.
class Wrapped:
def __init__(self):
self.a = 0
self.b = 1
class Proxy:
def __init__(self, wrapped):
object.__setattr__(self, 'wrapped', wrapped)
object.__setattr__(self, 'a', 2)
def __getattr__(self, attr):
return getattr(self.wrapped, attr)
def __setattr__(self, attr, value):
if attr in self.__dict__: # <-- Don't like this, hasattr doesn't work
object.__setattr__(self, attr, value)
elif hasattr(self.wrapped, attr):
setattr(self.wrapped, attr, value)
else: object.__setattr__(self, attr, value)
Тест-драйв:
>>> w = Wrapped()
>>> p = Proxy(w)
>>> p.a
2
>>> p.b
1
>>> p.a = 3
>>> p.a
3
>>> w.a
0
>>> p.b = 4
>>> p.b
4
>>> w.b
4
>>> p.c = 5
>>> p.c
5
>>> w.c
AttributeError: 'Wrapped' object has no attribute 'c'
1 ответ
Встроенный hasattr()
функция
реализуется путем вызова
getattr(object, name)
и посмотреть, вызывает ли этоAttributeError
или не.
Модуль проверки имеет getattr_static()
метод, который можно использовать для
Получать атрибуты без запуска динамического поиска через протокол дескриптора,
__getattr__()
или__getattribute__()
".
Используя этот метод, вы можете определить hasattr_static()
метод аналогичен hasattr()
, но звонит inspect.getattr_static(object, name)
вместо того getattr(object, name)
:
import inspect
def hasattr_static(object, name):
try:
inspect.getattr_static(object, name)
return True
except AttributeError:
return False
А затем используйте это в __setattr__()
метод вашего Proxy
класс как проверка:
def __setattr__(self, attr, value):
if hasattr_static(self, attr):
object.__setattr__(self, attr, value)
elif hasattr(self.wrapped, attr):
setattr(self.wrapped, attr, value)
else:
object.__setattr__(self, attr, value)
В качестве альтернативы вы можете использовать dir()
функция вместо __dict__
чтобы получить список атрибутов вашего объекта, или используйте inspect.getmembers()
.