Python &引用;方法“中缺少作为第一个参数的self”;。为什么在这种情况下需要自我?

Python &引用;方法“中缺少作为第一个参数的self”;。为什么在这种情况下需要自我?,python,pyqt5,Python,Pyqt5,我正在学习如何使用PyQt5开发一些简单的GUI应用程序。我学习Python也是因为它。课堂上有些事情我不明白 例如,这里我有一个简单的GUI代码: from PyQt5 import QtWidgets, QtCore import sys class Ui_MainWindow: def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.setWi

我正在学习如何使用PyQt5开发一些简单的GUI应用程序。我学习Python也是因为它。课堂上有些事情我不明白

例如,这里我有一个简单的GUI代码:

from PyQt5 import QtWidgets, QtCore
import sys

class Ui_MainWindow:
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setWindowTitle("Simple GUI")
        MainWindow.resize(800,600)

        self.button = QtWidgets.QPushButton(MainWindow)
        self.button.setGeometry(QtCore.QRect(10, 10, 91, 91))
        self.button.setObjectName("button1")
        self.button.setText("Button")

        self.new_dialog = QtWidgets.QDialog()

        self.button.clicked.connect(lambda: New_Dialog.setupDialog(self.new_dialog, "Simple Dialog"))

class New_Dialog:
    def setupDialog(window, window_name):
        window.setObjectName(window_name)
        window.setWindowTitle(window_name)
        window.resize(600,400)

        window.exec()

app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
代码生成一个带有按钮的简单主窗口。当我按下按钮时,会弹出一个新的对话框窗口(如图所示)


这是我想要的,但它产生了5个错误:

  • 方法应将“self”作为第一个参数

  • “New_Dialog”的实例没有“setObjectName”成员

  • “新建对话”的实例没有“setWindowTitle”成员

  • “新建对话框”的实例没有“调整大小”成员

  • “New_Dialog”的实例没有“exec”成员

  • 分析错误,我想知道:如果类的方法中没有
    self.variable
    ,为什么我总是要在方法中使用
    self
    作为参数

    当我添加
    self
    作为参数时,按下按钮时会显示以下错误:

    self.button.clicked.connect(lambda: New_Dialog.setupDialog(self.new_dialog, "Simple Dialog"))
    TypeError: setupDialog() missing 1 required positional argument: 'window_name'
    

    我做错了什么?

    正如查尔斯·达菲(Charles Duffy)所提到的,无论你是否想要(或使用它),你都会得到
    self
    。不管你怎么称呼它。在python类中创建实例方法时,
    self
    是该方法的重要组成部分——调用该方法时,它始终是第一个参数。如果您决定在方法定义中省略
    self
    ,那么在参数列表中列出的第一件事将是使用不同名称的
    self

    class foo:
      def bar(baz):
        print("self is having an identity crisis, he thinks his name is baz")
    
    在本例中,
    baz
    self
    是相同的对象。self一词的用法并不特别,我们都称之为同一事物只是惯例。但无论名称如何,它始终是您在参数列表中列出的第一项

    默认情况下,所有方法都是实例方法,除非另有明确声明。如果您确实不想要
    self
    ,并且永远不会使用它,请将该方法声明为
    @staticmethod

    @staticmethod
    def my_method():
      # can't use self here...
    
    但是静态方法总是有点可疑:如果它不与定义它的类的状态交互,它真的属于该类吗?还是应该将其移动到同一模块内的独立功能

    现在,如果您这样做:

    New_Dialog.setupDialog(new_dialog, "Simple Dialog")
    
    in实际上是在类本身上调用
    setupDialog
    方法,而不是在类的实例(对象)上调用。在这种情况下,Python不会自动传递
    self
    ,因为没有创建对象实例。通常,这样称呼是错误的,而真正的意图是:

    New_Dialog().setupDialog(new_dialog, "Simple Dialog")
    

    这里有一些很好的解释:

    相关(至少):“这是我想要的工作,但它会产生5个错误”除非你想要错误,这似乎是自相矛盾的说法。这些警告是由静态代码分析器生成的还是由实际错误生成的?它是由VS代码生成的。代码运行并生成一个窗口,该窗口带有一个按钮,当按下该按钮时会生成一个对话框窗口。self参数是必需的,因为Python总是将对象传递给第一个参数中的任何方法,因此如果您没有将self放在那里接受它,则将对象放入名为window的变量中。这可能是您想要的,但可能会让其他读者感到困惑,因为按照惯例,该参数的名称应始终为
    self
    。相反,如果你根本不想接受这个参数,就把它变成一个静态方法(使用
    @staticmethod
    decorator),而不是一个实例方法。@Luguecos删除这个问题:是的,我知道它有什么意义。我在方法中添加了
    self
    作为参数,并在
    Ui\u主窗口中调用它作为
    New\u Dialog.setupDialog(self.New\u Dialog,“Simple Dialog”)
    。然后发生以下错误:
    setupDialog()缺少1个必需的位置参数:“窗口名称”
    。我该怎么称呼它?因为它似乎在使用第一个参数作为
    self
    ,而不是它应该使用的
    window
    。我在上一条评论中不是很清楚。实际上,我声明为
    setupDialog(self、window、window\u name)
    ,并称为
    New\u Dialog.setupDialog(self.New\u Dialog,“Simple Dialog”)
    。这会产生错误:
    setupDialog()缺少1个必需的位置参数:“window\u name”
    。然后我调用了
    New\u Dialog.setupDialog(self,self.New\u Dialog,“Simple Dialog”)
    ,它工作得很好。然而,我不明白为什么在这种情况下,我需要在调用方法时显式地使用
    self
    ,有时我只能编写
    方法(variable1,variable2
    。当您将其称为
    New\u Dialog.setupDialog
    ,实际上是在类上调用
    setupDialog
    *,而不是类的实例。请尝试
    New\u Dialog().setupDialog(self.New\u Dialog,“Simple Dialog”)
    我想我理解。因此,调用
    New\u Dialog.setupDialog(…)
    我必须在类内。在类外时,它必须是
    新建对话框().setupDialog(…)
    ?您可能永远不需要调用
    新建对话框。setupDialog()
    像这样,您可能想要的是
    新建对话框().setupDialog()
    。请注意额外的
    ()
    在那里。这就产生了巨大的区别:在类上调用方法与在类实例上调用方法之间的区别。在这些东西成为第二天性之前,您几乎肯定不想在类本身上调用方法。