TypeError:“函数”缺少一个必需的位置参数:“ self”

问题描述

代码

class App:

    root = Tk()
    button1 = Button()
    button2 = Button()
    button3 = Button()

    img1 = PhotoImage(file="blueBox.png")
    img2 = PhotoImage(file="redBox.png")
    deckImage = PhotoImage(file="blackBox.png")

尝试调用以下三个函数之一后,会发生错误

    def showcolor1(self):
        if self.card1 != 0:
            self.card2 = 1
        else:
            self.card1 = 1

        self.button1.configure(image=self.getArrayValue(0))
        self.button1.configure(state=disABLED)
        self.setChoosenPicture(self.getArrayValue(0))

删除showcolor1/2/3将要调用函数,因为它们起作用了。使用Buttons命令调用这些函数只是一个问题:

    def showcolor2(self):
        if self.card1 != 0:
            self.card2 = 2
        else:
            self.card1 = 2

        self.button2.configure(image=self.getArrayValue(1))
        self.button2.configure(state=disABLED)
        self.setChoosenPicture(self.getArrayValue(1))

    def showcolor3(self):
        if self.card1 != 0:
            self.card2 = 3
        else:
            self.card1 = 3

        self.button2.configure(image=self.getArrayValue(1))
        self.button2.configure(state=disABLED)
        self.setChoosenPicture(self.getArrayValue(2))


    button1 = Button(master=root,text="",image=deckImage,state=norMAL,command=showcolor1)
    button1.pack()
    button2 = Button(master=root,command=showcolor2)
    button2.pack()
    button3 = Button(master=root,command=showcolor3)
    button3.pack()

    root.mainloop()

a = App()

这是完整的代码: 它应该显示3个黑色的按钮。如果您按“按钮1”,则应该更改其颜色。当您按下2个按钮时,它将检查它们是否具有相同的颜色。 ::

from tkinter import *
class App:
    
    root = Tk()
    testArray = [1,2,2]
    cAmount = 0
    card1 = 0
    card2 = 0
    button1 = Button()
    button2 = Button()
    button3 = Button()
    
    img1 = PhotoImage(file="blueBox.png")
    img2 = PhotoImage(file="redBox.png")
    deckImage = PhotoImage(file="blackBox.png")

    def checkCards(self):
        if self.testArray[self.card1] == self.testArray[self.card2]:
            print("CORRECT")
        elif self.testArray[self.card1] != self.testArray[self.card2]:
            print("FALSE")
            if self.card1 == 1 or self.card2 == 1:
                self.button1.configure(image=self.deckImage)
                self.button1.configure(state=norMAL)
            if self.card1 == 2 or self.card2 == 2:
                self.button2.configure(image=self.deckImage)
                self.button2.configure(state=norMAL)
            if self.card1 == 3 or self.card2 == 3:
                self.button3.configure(image=self.deckImage)
                self.button3.configure(state=norMAL)

    def setChoosenPicture(self):
        self.cAmount = self.cAmount + 1
        if self.cAmount == 2:
            self.checkCards()
            self.cAmount = 0
        else:
            return

    def getArrayValue(self,buttonIndex):
        if self.testArray[buttonIndex] == 1:
            return self.img1
        elif self.testArray[buttonIndex] == 2:
            return self.img2

    def showcolor1(self):
        if self.card1 != 0:
            self.card2 = 1
        else:
            self.card1 = 1

        self.button1.configure(image=self.getArrayValue(0))
        self.button1.configure(state=disABLED)
        self.setChoosenPicture(self.getArrayValue(0))

    def showcolor2(self):
        if self.card1 != 0:
            self.card2 = 2
        else:
            self.card1 = 2

        self.button2.configure(image=self.getArrayValue(1))
        self.button2.configure(state=disABLED)
        self.setChoosenPicture(self.getArrayValue(1))

    def showcolor3(self):
        if self.card1 != 0:
            self.card2 = 3
        else:
            self.card1 = 3

        self.button2.configure(image=self.getArrayValue(1))
        self.button2.configure(state=disABLED)
        self.setChoosenPicture(self.getArrayValue(2))


    button1 = Button(master=root,command=showcolor3)
    button3.pack()

    root.mainloop()


    a = App()

The Error Message

解决方法

我认为函数调用存在问题,因为通常如果您将self作为签名传递,则该函数应该在类内,并通过作为self传递的对象进行调用,因此问题是showcolor3( )是在类内部定义的? PFB链接以获取更多详细信息

use of self in python

,

您没有向showcolor3()函数发送参数。

如果要向函数发送参数,可以使用lambda函数:

button3 = tk.Button(master=root,text="",command=lambda self = instance: showcolor3(self))

顺便说一句,您似乎没有在一个类中定义showcolor函数,但是由于我看不到整个代码,因此无法确定。在这种情况下,如果要使用实例调用该函数,则必须在该类中定义该函数。

编辑:我看到您编辑了您的问题。您必须先创建一个类,然后为其实例创建方法。您的问题可能是对OOP的了解不足。查看OOP概念可能是个好主意。

,

您尚未在类中定义函数。如果存在“ self”参数,则必须在实例上调用该函数。例如,如果x是实例,则可以将其称为.child

,

代码的问题是,当您可能想稍后在顶级运行它时,class语句中正在运行太多的东西。当您要使用在类中定义的方法时,这尤其会引起问题。他们使用self,它应该引用该类的实例。但是,由于尚未完成创建类的操作,因此无法在类语句本身的内部创建实例。

这是一个很多示例,将引发与您的代码相同的错误:

class Foo:
    def bar(self):
        print("bar")

    bar()

    # this also won't work,though you won't get here due to the error above
    f = Foo()  # if you remove the line above,this will raise a NameError about Foo

要修复此问题,您需要将使用 方法的代码移出类主体。将其放在函数中可能很有意义,但是 也可以在顶层工作,如果更有意义的话。在我的非常简单的示例中,它可能做到了:

class Foo:
    def bar(self):
        print("bar")

# unindent here!
f = Foo()
f.bar()

在您的代码中,您可能希望更多按钮设置代码以__init__方法发生。在创建每个实例后,Python会自动调用该方法。您需要考虑一下当前正在设计的哪些类变量应该由所有实例共享,以及哪些应该特定于每个实例。尽管让一切实例属性可能是一个不错的选择,但我对您的课程设计知之甚少,无法告诉您什么是最好的。 __init__方法将自动传递self

这是您的App类的一个版本,它显示了Tkinter程序的更典型样式,所有数据都放在实例变量中,而不是类变量中:

class App:
    # get rid of all the class-variable code
    def __init__(self,root):
        self.root = root
        self.testArray = [1,2,2]
        self.cAmount = 0
        self.card1 = 0
        self.card2 = 0
    
        self.img1 = PhotoImage(file="blueBox.png")
        self.img2 = PhotoImage(file="redBox.png")
        self.deckImage = PhotoImage(file="blackBox.png")

        self.button1 = Button(master=root,image=self.deckImage,state=NORMAL,command=self.showcolor1)
        self.button1.pack()
        self.button2 = Button(master=root,command=self.showcolor2)
        self.button2.pack()
        self.button3 = Button(master=root,command=self.showcolor3)
        self.button3.pack()

    # the rest of the methods are the same


# unindent for some more top level code to start the app running
root = Tk()
app = App(root)
root.mainloop()

请注意,Button对象的初始化变化很小,它们现在使用的是command=self.showcolor1和类似的对象,而不仅仅是使用方法名称。

,

只需在所有函数中写出你的最后一行,一切都很完美,我运行它,但我遇到了这个错误,只是尝试一下。

from tkinter import *


class App:

    root = Tk()
    testArray = [1,2]
    cAmount = 0
    card1 = 0
    card2 = 0
    button1 = Button()
    button2 = Button()
    button3 = Button()

    img1 = PhotoImage(file="blueBox.png")
    img2 = PhotoImage(file="redBox.png")
    deckImage = PhotoImage(file="blackBox.png")

    def checkCards(self):
        if self.testArray[self.card1] == self.testArray[self.card2]:
            print("CORRECT")
        elif self.testArray[self.card1] != self.testArray[self.card2]:
            print("FALSE")
            if self.card1 == 1 or self.card2 == 1:
                self.button1.configure(image=self.deckImage)
                self.button1.configure(state=NORMAL)
            if self.card1 == 2 or self.card2 == 2:
                self.button2.configure(image=self.deckImage)
                self.button2.configure(state=NORMAL)
            if self.card1 == 3 or self.card2 == 3:
                self.button3.configure(image=self.deckImage)
                self.button3.configure(state=NORMAL)

    def setChoosenPicture(self):
        self.cAmount = self.cAmount + 1
        if self.cAmount == 2:
            self.checkCards()
            self.cAmount = 0
        else:
            return

    def getArrayValue(self,buttonIndex):
        if self.testArray[buttonIndex] == 1:
            return self.img1
        elif self.testArray[buttonIndex] == 2:
            return self.img2

    def showcolor1(self):
        if self.card1 != 0:
            self.card2 = 1
        else:
            self.card1 = 1

        self.button1.configure(image=self.getArrayValue(0))
        self.button1.configure(state=DISABLED)
        self.setChoosenPicture(self.getArrayValue(0))

    def showcolor2(self):
        if self.card1 != 0:
            self.card2 = 2
        else:
            self.card1 = 2

        self.button2.configure(image=self.getArrayValue(1))
        self.button2.configure(state=DISABLED)
        self.setChoosenPicture(self.getArrayValue(1))

    def showcolor3(self):
        if self.card1 != 0:
            self.card2 = 3
        else:
            self.card1 = 3

        self.button2.configure(image=self.getArrayValue(1))
        self.button2.configure(state=DISABLED)
        self.setChoosenPicture(self.getArrayValue(2))

    button1 = Button(
        master=root,image=deckImage,command=showcolor1
    )
    button1.pack()
    button2 = Button(
        master=root,command=showcolor2
    )
    button2.pack()
    button3 = Button(
        master=root,command=showcolor3
    )
    button3.pack()

    root.mainloop()

a = App() //This needs to be out