Порядок множественного наследования в Python3 / PyQt

Я столкнулся с проблемой при использовании множественного наследования с PyQt, исходным кодом Программа 1 #, как показано ниже:

#!python3
import sys;
from PyQt5.QtWidgets import *;
from PyQt5.QtGui import *;
from PyQt5.QtCore import *;

class WP_Widget(QWidget):
    def __init__(self):
        print("WP_Widget init");
        super().__init__();

class WP_Line(QLineEdit):
    def __init__(self, text='',*args, **kargs):
        super().__init__();
        self.setText(text);

class Widget_C(WP_Widget, WP_Line):
#class Widget_C(WP_Line, WP_Widget):
    def __init__(self):
        print('Widget_C self = ', self)
        super().__init__();

class App(QWidget):
    def __init__(self):
        super().__init__();
        fname = Widget_C();
        self.left = 100
        self.top = 100
        self.width = 100
        self.height = 100
        self.show();

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

При выполнении он покажет ошибку как:

AttributeError: 'Widget_C' object has no attribute 'setText'

Если изменить определение Widget_C из

class Widget_C(WP_Widget, WP_Line):

к

class Widget_C(WP_Line, WP_Widget):

Он будет работать успешно.

Я предполагаю, что это будет связано с ТОиР в Python3, поэтому я пишу еще один программа 2 # для имитации состояния:

#!python3

class QWidget():
    def __init__(self):
        print("Base QWidget init.");

class QLineEdit(QWidget):
    def __init__(self):
        print('LineEdit init');
        super().__init__();

    def setText(self, text):
        print('setText called');

class WP_Widget(QWidget):
    def __init__(self):
        print('WP_Widget Init');
        super().__init__()

class WP_Line(QLineEdit):
    def __init__(self, text='',*args, **kargs):
        print('WP_Line init');
        super().__init__();
        self.setText(text)

class Widget_C(WP_Widget, WP_Line):
#class Widget_C(WP_Line, WP_Widget):
    def __init__(self):
        super().__init__()

c_test = Widget_C()

Но независимо от того, какая последовательность наследует Wiget_C,

class Widget_C(WP_Line, WP_Widget):

или же

class Widget_C(WP_Widget, WP_Line):

оба они будут работать нормально.

Так может ли кто-нибудь помочь:

  1. Объясните, почему программа 1 # не работает при определении как class Widget_C(WP_Widget, WP_Line):, ТОиР - это всего лишь мое предположение.
  2. Почему программа 2 # может нормально работать в обоих условиях?
  3. Помогите изменить программа 2 #, чтобы воспроизвести состояние программа 1 #.

Python и порядок методов при множественном наследовании кое-что объясняет о ТОиР, это связано с моим вопросом, но не совсем с ответом. Если порядок наследования один и тот же, мои программа 1 # и программа 2 не должны иметь разных результатов, поэтому ключевым моментом является то, почему программа 1 # и программа 2 имеют разные явления.

Я не знаю подробностей реальных классов WP_Line и WP_Widget, но я предполагаю, что один из них не вызывает совместно super().__init__() из своего собственного метода __init__, что означает, что другая часть множественного наследования никогда не инициализируется должным образом. . В вашей пользовательской версии ваши классы делать выполняют соответствующие вызовы super, поэтому проблема не возникает.

Blckknght 11.04.2018 05:32

QLineEdit наследуется от QWidget. Как вы думаете, необходимо ли наследовать от QWidget, если он уже наследуется от QLineEdit?

eyllanesc 11.04.2018 06:18

Возможный дубликат Python и порядок методов при множественном наследовании

eyllanesc 11.04.2018 06:18

@Blckknght Спасибо за ваш ответ, и я согласен с вашим мнением, и если моя пользовательская версия работает нормально, это может быть вызвано PyQt? Я не уверен.

whisper 11.04.2018 07:33

@eyllanesc Спасибо за помощь. QLineEdit наследуется от QWidget - это просто индивидуальная программа испытаний, написанный мной, а не импортированный из PyQt. В реальном случае. Нет необходимости наследовать от QWidget.

whisper 11.04.2018 07:34

Как и заявлено в документах, pyqt не поддерживает множественное наследование классов qt. Другими словами, это не будет работать так, как вы обычно ожидаете от обычного Python. Сказав это, это сообщение в блоге имеет некоторые интересные идеи и обходные пути (но обратите внимание, что он был изначально написан для pyqt4, поэтому некоторые вещи теперь могут быть устаревшими). Вам, вероятно, также следует прочитайте это.

ekhumoro 11.04.2018 21:06

@ekhumoro Спасибо, это именно тот ответ, которого я ожидал. Возможно, мне следует избегать использования множественного наследования с PyQt в будущем.

whisper 12.04.2018 05:11
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
540
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

эхуморо дал именно то, что мне нужно.

Как и заявлено в документах, pyqt не поддерживает множественное наследование классов qt. Другими словами, это не будет работать так, как вы обычно ожидаете от обычного Python.

Сказав это, это сообщение в блоге имеет некоторые интересные идеи и обходные пути (но обратите внимание, что он был изначально написан для pyqt4, поэтому некоторые вещи теперь могут быть устаревшими).

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