Подтвердить что ты не робот

Избегайте предупреждения Pylint E1101: "Экземпляр.. не имеет.. member" для класса с динамическими атрибутами

Представьте себе функцию, которая динамически добавляет атрибуты к объекту с помощью setattr. Причиной этого является то, что я хочу сопоставить некоторую внешнюю структуру (например, определенное дерево параметров) с объектом:

my_object = SomeClass()
apply_structure(my_object, some_descriptor)
my_object.device1.enabled = True

Технически это работает, но, конечно же, Пилинт жалуется, что "device1" не является членом SomeClass.

Я мог бы отключить предупреждение, но это было бы плохо (потому что я все еще хочу получить предупреждение во всех случаях, когда атрибут не существует из-за неправильной орфографии и т.д.).

Существует ли общий и законный (Pylint-proof) способ динамического добавления элементов в объект, который не приводит к предупреждениям?

Альтернативно: могу ли я отключить Pylint только для одного объекта, а не для строки/блока/файла?

Объяснение

Вы можете задаться вопросом, почему я должен динамически оснащать объект атрибутами-членами, когда планирую получить доступ к этим атрибутам жестко-кодированным способом позже.

Причина в том, что у меня есть динамическая часть программы (где происходит оформление) и статическая часть, которая специализирована для определенного сценария. Таким образом, я мог создавать статический класс для этого сценария, но это было бы излишним во многих ситуациях.

Следующий специализированный код может разрешить доступ к некоторому параметру устройства, которое может быть подключено к некоторой шине:

class MyDeviceHandler:
   on_get_some_subtree_element(self):
      return _some_internal_value
   on_set_some_subtree_element(self, value):
      _some_internal_value = value

dev = MyDeviceHandler()

decorate_object_with_device_structure(dev, 'some/attached/device')

dev.some.subtree.element = 5       <--- will call the set-callback
x = dev.some.subtree.element       <--- will call the get-callback

Таким образом, структура за 'some/attached/device' может быть произвольной и очень сложной, и я не хочу воспроизводить ее в структуре класса.

Одним из способов избавиться от этого предупреждения было бы создание/доступ к дереву dict:

dev['some']['subtree']['element'] = 5

Но это труднее писать и не приятно читать - я бы сделал это только для того, чтобы успокоить Пилинту.

4b9b3361

Ответ 1

Просто чтобы предоставить ответ, который работает для меня сейчас - как Компилятор предложил вам добавить правило для проблемного класса в ваших проектах .pylintrc:

[TYPECHECK]
ignored-classes=Fysom,MyClass

Ответ 2

Вы можете использовать подкласс:

class MyClass(Someclass):
    def init(self):
       super().__init__()
       self.device1 = WhateverDevice1Is()

my_object = MyClass()
apply_structure(my_object, some_descriptor)
my_object.device1.enabled = True

Примечание: Python3

Ответ 3

Эта страница описывает ошибку и предоставляет простой способ ее устранения прямо в коде. ТЛ; др

Используется при доступе к объекту (переменной, функции,…) для несуществующего члена.

Ложные срабатывания: это сообщение может сообщать об элементах объекта, которые создаются динамически, но существуют в момент обращения к ним.

Комментатор упоминает, что его можно отключить в одной строке вверху файла с помощью # pylint: disable=no-member. Я также обнаружил, что вы можете использовать # pylint: disable=E1101 на основе этой записи Reddit.