Почему нельзя вызвать атрибут класса?

Я модифицирую код openstack-nova.

После добавления RESTful api я получил эту ошибку:

eption during message handling: AttributeError: 'SchedulerReportClient' object has no attribute 'obj_to_primitive'
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server Traceback (most recent call last):
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server   File "/usr/lib/python2.7/site-packages/oslo_messaging/rpc/server.py", line 163, in _process_incoming
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server     res = self.dispatcher.dispatch(message)
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server   File "/usr/lib/python2.7/site-packages/oslo_messaging/rpc/dispatcher.py", line 268, in dispatch
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server     return self._do_dispatch(endpoint, method, ctxt, args)
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server   File "/usr/lib/python2.7/site-packages/oslo_messaging/rpc/dispatcher.py", line 195, in _do_dispatch
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server     return self.serializer.serialize_entity(ctxt, result)
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server   File "/openstack/lib/python2.7/site-packages/nova/rpc.py", line 130, in serialize_entity
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server     return self._base.serialize_entity(context, entity)
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server   File "/openstack/lib/python2.7/site-packages/nova/objects/base.py", line 237, in serialize_entity
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server     entity)
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server   File "/openstack/lib/python2.7/site-packages/nova/objects/base.py", line 223, in _process_iterable
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server     for k, v in values.items()})
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server   File "/openstack/lib/python2.7/site-packages/nova/objects/base.py", line 223, in <dictcomp>
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server     for k, v in values.items()})
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server   File "/openstack/lib/python2.7/site-packages/nova/objects/base.py", line 245, in serialize_entity
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server     entity = entity.obj_to_primitive()
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server   File "/openstack/lib/python2.7/site-packages/nova/scheduler/client/__init__.py", line 37, in __run_method
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server     return getattr(self.instance, __name)(*args, **kwargs)
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server AttributeError: 'SchedulerReportClient' object has no attribute 'obj_to_primitive'
2018-08-30 23:08:10.904 1637 ERROR oslo_messaging.rpc.server 

Связанный код:

def serialize_entity(self, context, entity):
    if isinstance(entity, (tuple, list, set, dict)):
        entity = self._process_iterable(context, self.serialize_entity, entity)
    elif (hasattr(entity, 'obj_to_primitive') and callable(entity.obj_to_primitive)):
        entity = entity.obj_to_primitive()
    return entity

Мой вопрос: hasattr(entity, 'obj_to_primitive') верен, так почему же entity.obj_to_primitive() вызывает исключение?

obj_to_primitive также можно вызвать. И hasattr(entity, 'obj_to_primitive'), и callable(entity.obj_to_primitive) верны.
Don_Chen 31.08.2018 05:32
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
91
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Посмотрите на последнюю строку трассировки стека. Вы являются вызываете «метод», но это всего лишь оболочка для соответствующего метода на self.instance, а тотgetattr дает сбой. При поиске внешнего атрибута удалось создать оболочку, что порадовало hasattr, и действительно, оболочка - это callable.

Тест hasattr работал бы, если бы getattr(self.instance, __name) вычислялся, когда оболочка была созданный. Если единственная цель оболочки - быть называется (а не, скажем, иметь собственные методы), она также может выполнить собственную проверку callable. Но Python отдает себя EAFP, так что вот и мы.

Другие вопросы по теме