Unikaj Ostrzeżenia Pylint E1101: "instancja. nie ma. member ' dla klasy z atrybutami dynamicznymi

Wyobraź sobie funkcję, która dynamicznie dodaje atrybuty do obiektu za pomocą setattr. Powodem tego jest to, że chcę odwzorować jakąś zewnętrzną strukturę (np. dane drzewo parametrów) na obiekt:

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

Technicznie to działa, ale oczywiście pylint słusznie narzeka, że "device1" nie jest członkiem SomeClass.

Mógłbym wyłączyć ostrzeżenie, ale byłoby to złe (ponieważ nadal chcę otrzymać ostrzeżenie we wszystkich przypadkach, gdy atrybut nie istnieć z powodu błędnego zapisu itp.).

Czy istnieje wspólny i legalny (odporny na Pylint) sposób dynamicznego dodawania członków do obiektu, który nie prowadzi do ostrzeżeń?

Alternatywnie: Czy Mogę wyłączyć Pylint tylko dla jednego obiektu zamiast linii/bloku/pliku?

Wyjaśnienie :

Możesz się zastanawiać, dlaczego powinienem wyposażyć obiekt w atrybuty członka dynamicznie, kiedy planuję uzyskać dostęp do tych atrybutów w sposób kodowany na twardo później.

Powodem jest: I posiada dynamiczną część programu (w której występuje Dekoracja) oraz statyczną część, która jest wyspecjalizowana dla pewnego scenariusza . Więc ja mógłbym również stworzyć statyczną klasę dla tego scenariusza, ale byłoby to przesadą w wielu sytuacjach.

Następujący kod specialized może umożliwić dostęp do jakiegoś parametru urządzenia, które może być dołączone do jakiejś magistrali:

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

Więc struktura za 'some/attached/device' może być dowolna i bardzo złożona i nie chcę tego reprodukować w strukturze klasowej.

Jednym ze sposobów pozbycia się tego ostrzeżenia byłoby stworzenie / dostęp do drzewa bazującego na dict:

dev['some']['subtree']['element'] = 5
[7]}ale to jest trudniejsze do napisania, a nie miłe do przeczytania - zrobiłbym to tylko po to, by uciszyć Pylinta.
Author: frans, 2016-03-14

6 answers

Tylko po to, aby dać odpowiedź, która teraz działa dla mnie - jak kompilator zasugerował, możesz dodać regułę dla problematycznej klasy w swoich projektach .pylintrc:

[TYPECHECK]
ignored-classes=Fysom,MyClass
 56
Author: frans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:29

Ta strona opisuje błąd i daje łatwy sposób adresowania go bezpośrednio w kodzie. tl; dr

używany, gdy obiekt (zmienna, funkcja, ...) jest dostępny dla nieistniejącego członka.

False positives: ta wiadomość może zgłaszać elementy obiektów, które są tworzone dynamicznie, ale istnieją w momencie, w którym są dostępne.

Komentator wspomina, że można go wyłączyć w jednej linii u góry Pliku za pomocą # pylint: disable=no-member. Odkryłem również, że można użyj # pylint: disable=E1101 na podstawie tego wpisu .

 40
Author: user2577,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-12 01:53:41

PyLint podaje tego typu błędy w dwóch przypadkach Link :

  • Używany, gdy obiekt (zmienna, funkcja, ...) jest dostępny dla członek nieistniejący.

  • False positives: ta wiadomość może zgłaszać członków obiektu, którzy są tworzone dynamicznie, ale istnieją w momencie, w którym są dostępne.

Ponieważ ten błąd jest identyfikowany jako błąd E1101. Możesz rozwiązać ten problem, dodając następujący wiersz w kodzie.

# pylint: disable=E1101
 16
Author: Ashwani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-17 05:50:32

Udało mi się uniknąć tego ostrzeżenia, dodając metodę __getattr__ do mojej klasy, którą wywołuje python, gdy atrybut nie został znaleziony na obiekcie. Chociaż zdecydowanie nie jest to najczystsze rozwiązanie, zadziałało w moim konkretnym przypadku użycia, ponieważ pylint uważa obiekt za prawidłowy.

import warnings
class AppConfiguration(object):     
    ... 
    def __getattr__(self, name):
        ''' will only get called for undefined attributes '''
        warnings.warn('No member "%s" contained in settings config.' % name)
        return ''

Więcej informacji o metodzie __getattr__ można znaleźć tutaj.

 6
Author: Joshua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-17 23:37:10

Spróbuj tego! Mój problem rozwiązany!

Pylint nie rozumie dynamicznego pliku Django. Tak więc, musimy nauczyć czym jest Django do Pylint

*dla vscode w Windows 10 *

$ pip install pylint-django
$ cd your_project_folder
$ code . // run vscode  

Install extension for Python, Django Snippets, Django Template in vscode

Otwórz .vscode/settings.json w vscode i dodaj:

{
   "python.linting.pylintEnabled": true,
   "python.linting.enabled": true,
   "python.pythonPath": "venv\\Scripts\\python.exe",
   "python.linting.pylintArgs": [
       "--load-plugins",
       "pylint_django"
   ],
}
 4
Author: yongtaek jun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-22 14:15:12

Dla mnie właśnie instalacja pylint-django rozwiązała problem:

pip install pylint-django
 1
Author: mona-mk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-02 08:57:03