Python在init之外定义gui变量

时间:2018-12-13 09:00:14

标签: python user-interface pyside2

我正在使用PySide2来定义我的工具的界面,并且我通常会初始化__init__之外的所有界面项目,以免使其膨胀(其他重要变量保留在__init__中)。

不幸的是,我使用PyCharm作为编辑器,它给了我很多警告:

  

在__init __

之外定义的实例属性'foobar'

这是我要做什么的一个简单示例:

from PySide2 import QtWidgets


class MyTool(QtWidgets.QWidget):

    def __init__(self, parent=None):
        super(MyTool, self).__init__(parent)

        self.create_gui()

    def create_gui(self):
        # Complains about all variables below!

        self.awesome_checkbox = QtWidgets.QCheckBox(parent=self)

        self.awesome_button = QtWidgets.QPushButton(parent=self)

        self.awesome_label = QtWidgets.QLabel(parent=self)

        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addWidget(self.awesome_checkbox)
        self.main_layout.addWidget(self.awesome_button)
        self.main_layout.addWidget(self.awesome_label)
        self.setLayout(self.main_layout)

现在,我知道一种解决方案是将__init__中的这些变量初始化为None,但是我可以使用相当复杂的接口,因此使用起来会很漫长。

我的问题是我目前在做的是真正的亵渎吗?我知道变量在技术上不在__init__之外,但是无论如何,该方法仍在构造函数中被调用!

1 个答案:

答案 0 :(得分:0)

嗯,简短的答案是:不,这不是“真正的亵渎”。

创建所有实例属性并确保它们在初始化程序中处于一致状态被认为是一种好习惯,因为它使代码更易于阅读(您只能通过一种方法来读取对象的属性),并避免潜在的危险由方法创建的属性错误,该方法在访问属性之前可能不会总是被调用。这就是为什么大多数短绒猫(默认情况下)会警告您的原因,它本身就是一件好事,因为它可以帮助您在潜在的错误投入生产之前就将其发现。

现在确实存在将实例初始化的一部分委派给不同方法的情况,即当这些属性相互依赖以及其他一些外部因素并且可能必须在实例的生命周期中一起重置/更新时,或者要让子类覆盖初始化的这一部分而不必覆盖__init__()方法本身(请参阅GOF的“模板方法”模式)。

对于具有复杂初始化的类(这是GUI组件的典型情况),出于可读性原因,将设置拆分为不同的方法也很有意义-当涉及到50行以上的初始化时,它并不是最佳选择可读性-就我而言,我可能会做一些类似的事情,并可能进行了一些改进:首先将其设置为“受保护”方法(将其命名为_create_gui()-前导下划线是受保护属性的命名约定/方法),然后添加一个保护措施以防止该方法执行两次(假设该方法仅应从初始化方法中调用一次,并且当然不应作为公共API的一部分)。然后,我将添加几个linter指令(这些指令是linter寻找的特殊格式的注释),以使linter和阅读此代码的任何人都清楚,这样做是有意的设计选择,而不是菜鸟的错误。