main() 缺少 1 个必需的位置参数:'self'

main() missing 1 required positional argument: 'self'

这是我的代码。我正在学习 python.

中制作贪吃蛇游戏的教程
import math, random, pygame

class cube(object):
    rows = 20
    w = 500
    def __init__(self,start,dirnx=1,dirny=0,color=(255,0,0)):
        self.pos = start
        self.dirnx = 1
        self.dirny = 0
        self.color = color

    def move(self, dirnx, dirny):
        self.dirnx = dirnx
        self.dirny = dirny
        self.pos = (self.pos[0] + self.dirnx, self.pos[1] + self.dirny)
        
    def draw(self, surface, eyes=False):
        dis = self.w // self.rows  
        i = self.pos[0]
        j = self.pos[1] 
        pygame.draw.rect(surface, self.color, (i*dis+1,j*dis+1, dis-2, dis-2))
        if eyes: 
            centre = dis//2
            radius = 3
            circleMiddle = (i*dis+centre-radius,j*dis+8) 
            circleMiddle2 = (i*dis + dis -radius*2, j*dis+8) 
            pygame.draw.circle(surface, (0,0,0), circleMiddle, radius)
            pygame.draw.circle(surface, (0,0,0), circleMiddle2, radius) 


class snake(object):
    body = []
    turns = {}
    def __init__(self, color, pos):
        self.color = color
        self.head = cube(pos)  
        self.body.append(self.head) 

        self.dirnx = 0 
        self.dirny = 1 

    def move():
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()

            keys = pygame.key.get_pressed()
            
            for key in keys: 
                if keys[pygame.K_LEFT]:
                    self.dirnx = -1
                    self.dirny = 0 
                    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny] 
                    
                elif keys[pygame.K_RIGHT]:
                    self.dirnx = 1
                    self.dirny = 0
                    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

                elif keys[pygame.K_UP]:
                    self.dirnx = 0
                    self.dirny = -1
                    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]

                elif keys[pygame.K_DOWN]:
                    self.dirnx = 0
                    self.dirny = 1
                    self.turns[self.head.pos[:]] = [self.dirnx, self.dirny]
            
        for i, c in enumerate(self.body): 
            p = c.pos[:] 
            if p in self.turns: 
                turn = self.turns 
                c.move(turn[0], turn[1]) 
                if i == len(self.body)-1: 
                    self.turns.pop(p)
            else: 
                if c.dirnx == -1 and c.pos[0] <= 0: c.pos = (c.rows-1, c.pos[1]) 
                elif c.dirnx == 1 and c.pos[0] >= c.rows-1: c.pos = (0,c.pos[1]) 
                elif c.dirny == 1 and c.pos[1] >= c.rows-1: c.pos = (c.pos[0], 0) 
                elif c.dirny == -1 and c.pos[1] <= 0: c.pos = (c.pos[0],c.rows-1)
                else: c.move(c.dirnx, c.dirny)

    def reset(self, pos):
        pass

    def addCube(self):
        tail = self.body[-1] #-1 is the last element in that list
        dx, dy = tail.dirnx, tail.dirny #dx and dy is direction of x and direction of y

        if dx == 1 and dy == 0:
            self.body.append(cube((tail.pos[0]-1,tail.pos[1])))  
        elif dx == -1 and dy == 0:
            self.body.append(cube((tail.pos[0]+1,tail.pos[1])))
        elif dx == 0 and dy == 1:
            self.body.append(cube((tail.pos[0],tail.pos[1]-1)))
        elif dx == 0 and dy == -1:
            self.body.append(cube((tail.pos[0],tail.pos[1]+1)))

            self.body[-1].dirnx = dx 
            self.body[-1].dirny = dy
    def draw(self, surface):
        for i, c in enumerate(self.body):
            if i==0: 
                c.draw(surface, True) 
            else:
                c.draw(surface) 

    def drawGrid(w, rows, surface):
        sizeBtwn = w // rows  

        x = 0  
        y = 0  
        for l in range(rows):
            x = x + sizeBtwn
            y = y + sizeBtwn 

            pygame.draw.line(surface, (255,255,255), (x,0),(x,w))
            pygame.draw.line(surface, (255,255,255), (0,y),(w,y))

    def redrawWindow(surface):
        global width, rows, s, snack #ADD snack to this line  
        surface.fill((0,0,0))
        s.draw(surface)
        snack.draw(surface) #NEW
        drawGrid(width, rows, surface) 
        pygame.display.update() 

    def randomSnack(rows, item):
        positions = item.body
        while True:
            x = random.randrange(rows) 
            y = random.randrange(rows)
            if len(list(filter(lambda z:z.pos == (x,y), positions))) > 0:
                continue
            else:
                break
            return (x.y)

    def message_box(subject, content):
        pass

    def main(self):
        global width, rows, s, snack
        self.move = move
        width = 500 
        height = 500 
        rows = 20 
        win = pygame.display.set_mode((width, width)) 
        s = snake ((255,0,0), (10,10))
        snack = cube(randomSnack(rows, s), color = (0,255,0))
        flag = True
        
        clock = pygame.time.Clock() 
        
        while flag:
            pygame.time.delay(50)
            clock.tick(10)
            s.move()
            if s.body[0] == snake.pos: #Checks if the head collides with the snack
                s.addCube() #Adds a new cube to the snake
                snack = cube(randomSnack(rows, s), color=(0,255,0)) #Creates a new snack object

            redrawWindow(win) 

main()

但后来我不断收到这个我似乎无法修复的错误:

Traceback (most recent call last):
File "C:\Users\Ammar Khan\AppData\Local\Programs\Python\Python37\Snake Game Tutorial #4.py", line 186, in <module> main()
TypeError: main() missing 1 required positional argument: 'self'

在代码中,缩进显示您的 main () 函数在您的 snake class 中,drawGrid() 以下的所有方法也是如此。您需要将它们全部向后移动一个缩进,才能将它们从 class 中取出。然后删除 def main() 中的 self 参数。这应该可以解决该问题。

我注意到的另一件事是 snake() class 中的 move() 方法缺少它应该具有的 self 参数。应该是move(self)。 class 中的所有实例方法必须有一个 self 参数作为它们的第一个参数(实际上 self 只是约定俗成的名称,它可以是任何东西,但你应该使用 self 否则会造成混淆)。您不通过传递该参数来调用它,它由 python 填充并引用实例。

很多初学者 python 程序员在第一次开始制作自己的 classes 时都会被这个问题困扰。这可能看起来令人困惑,因为当你调用它时那个参数不存在,所以看起来你用一个参数调用它似乎太少了。

我将说明它是如何工作的。如果你有一个 class player 并且想调用它的 update() 方法,你可以用它需要的任何参数调用 player.update(...) 。 Python 在调用该实例方法时,采用实例引用 player 并将其放在您自己传递的所有“...”参数前面,并最终出现在 self 参数中.这就是实例方法如何获取对自己实例的引用,它可以使用该实例来访问其内部属性。我希望这有助于澄清这一点。

我注意到另外两件事:

1) 您的代码中有两个 class cube() 定义。第二个覆盖第一个导致它被忽略。它们的开头相同,所以这可能是拼写错误或复制和过去的错误?

2) 你好像打错了:

if s.body[0] == snake.pos: #Checks if the head collides with the snack

从评论来看,我认为应该是snack.pos,而不是蛇。

您需要创建 class 的对象,然后对其应用 main 方法。它会很好地工作。

like this:
sanke1 = snake()
sanke1.main()

解决方法如下:

    def a(self=a) : return self
    b = a
    b()

这将 return 本身。