как справиться с R0915: Слишком много утверждений (69/50) (слишком много утверждений) в pylint?

#python #pyqt5 #pylint #pep8

Вопрос:

У меня есть код Python (графический интерфейс с несколькими графическими элементами) в PyQt5 . Как я могу сократить код в соответствии с рекомендациями PEP8 50 операторов на функцию? Подходит ли разбивать определения графических элементов на несколько функций?

     def __init__(self, pulse_number, on_time, off_time, x, y, offset):
        self.offset = offset
        self.laser_pulse_n = pulse_number
        self.laser_on_time = on_time
        self.laser_off_time = off_time
        self.laser_x_loc = x
        self.laser_y_loc = y
        # set window properties
        self.setMinimumSize(QSize(250, 300))
        self.setWindowTitle("Laser settings")

        self.int_validator = QIntValidator()

        # LASER
        # Create pulse number label
        self.pulse_number_label = QLabel(self)
        self.pulse_number_label.setGeometry(QRect(10, 0, 80, 20))
        self.pulse_number_label.setText("Pulse n.:")

        # Create pulse number input box
        self.pulse_number_input = QLineEdit(self)
        self.pulse_number_input.setGeometry(QRect(60, 0, 40, 20))
        self.pulse_number_input.setText(str(self.laser_pulse_n))
        self.pulse_number_input.setValidator(self.int_validator)

        # Create laser on label...
        
        ...

        # Apply button
        self.validate_button = QPushButton(self)
        self.validate_button.setGeometry(QRect(10, 240, 230, 40))
        self.validate_button.setToolTip("Click to save settings")
        self.validate_button.setFont(QFont('Times', 20))
        self.validate_button.setText("Apply")
        self.validate_button.clicked.connect(self.validate_settings)

 

Комментарии:

1. В PEP 8 не содержится никаких рекомендаций относительно длины функций. Там нет упоминания о 50 утверждениях — это просто изобретение авторов pylint и не имеет ничего общего с PEP 8.

Ответ №1:

На мой взгляд, есть два решения : вы можете отключить это предупреждение, потому что PyQt как бы вынуждает вас кодировать его таким образом. Понятнее иметь каждое определение атрибута в конструкторе, и если вы создадите подфункцию, вы все равно получите attribute-defined-outside-init предупреждение. Другим решением было бы немного провести рефакторинг и создать средство настройки свойств или функцию для настройки объекта.

Т. е., например, исходя из этого:

         ...
        self.validate_button = QPushButton(self)
        self.validate_button.setGeometry(QRect(10, 240, 230, 40))
        self.validate_button.setToolTip("Click to save settings")
        self.validate_button.setFont(QFont('Times', 20))
        self.validate_button.setText("Apply")
        self.validate_button.clicked.connect(self.validate_settings)
 

К этому:

         ...
        self.validate_button = self.validate_settings


    @property
    def validate_button(self):
        return self.__validate_button

    @validate_button.setter
    def validate_button(self, validate_settings):
        self.__validate_button = QPushButton(self)
        self.__validate_button.setGeometry(QRect(10, 240, 230, 40))
        self.__validate_button.setToolTip("Click to save settings")
        self.__validate_button.setFont(QFont('Times', 20))
        self.__validate_button.setText("Apply")
        self.__validate_button.clicked.connect(validate_settings)
 

Это имеет преимущества, позволяющие изменять атрибуты позже, если вам это необходимо.

Или это:

         ...
        self.validate_button = QPushButton(self)
        self.__init_validate_button()

    def __init_validate_button(self):
        self.validate_button.setGeometry(QRect(10, 240, 230, 40))
        self.validate_button.setToolTip("Click to save settings")
        self.validate_button.setFont(QFont('Times', 20))
        self.validate_button.setText("Apply")
        self.validate_button.clicked.connect(self.validate_settings)
 

Это позволяет сохранять класс неизменным