嵌套类的函数将'self'视为参数 - Python

时间:2018-03-22 00:57:56

标签: python class arguments typeerror inner-classes

我正在尝试制作一个井字游戏。

我有一个类,Player和一个嵌套类,Check,在其中。

这是我的完整代码:

class Player: # Player class
'''this is a class for the player in a tic-tac-toe game'''

def __init__(self, counter): # initialize
    self.counter = counter # set player counter

def place(self, x, y): # functions directly interfering with data can global
    '''this function helps with placing counters on the grid'''
    global grid
    grid[y][x] = self.counter

class Check:
    '''checks if a player wins or loses'''

    def check_vertical(self, grid): # checking functions avoid globaling
        '''check if there are three counters in a row vertically'''
        for row in range(3):
            if grid[row][0] and grid[row][1]\
               and grid[row][2] == self.counter:
                return True

    def check_horiontal(self, grid): # checking functions avoid globaling
        '''check if there are three counters in a row horizontally'''
        for column in range(3):
            if grid[0][column] and grid[1][column]\
               and grid[2][column] == self.counter:
                return True

    def check_diagonal(self, grid): # checking functions avoid globaling
        '''check if there are three counters in a row diagonally'''
        if grid[0][0] and grid[1][1] and grid[2][2] or\
           grid[0][2] and grid[1][1] and grid[2][0] == self.counter:
            return True

    def check_all(self, grid):
        '''check if there are three counters in a row in any direction'''
        return (self.check_vertical(self, grid) or\
                self.check_horizontal(self, grid) or\
                self.check_diagonal(self, grid))

所以,当我尝试在shell中测试它时:

>>> player = Player("O")
>>> player.Check.check_all(tic_tac_toe_grid)

Python抛出错误:

Traceback (most recent call last):
  File "<pyshell#34>", line 1, in <module>
    a.Check.check_all(grid)
TypeError: check_all() missing 1 required positional argument: 'grid'

Python认为self是必需的参数。

我的代码出了什么问题?

2 个答案:

答案 0 :(得分:1)

这与Check作为嵌套类无关。

首先,Python认为self是必需的参数,因为它是。您明确地将其声明为参数:

def check_all(self, grid):

当您正常调用方法时,在类的实例(如thingy.method(foo))上,Python会将thingy转换为self

但是您并未在Check的实例上调用该方法,而是在Check本身上调用它。这是合法的,但不寻常。当你这样做时,你需要明确地将一个实例传递给self

这就是你真正的问题 - 你甚至不会拥有一个实例。并且可能是您使用属性和__init__方法以及所有内容创建了类,因为您需要该类的实例。 (如果你需要一个类,那么你应该摆脱这个类,只需要创建Player或顶级函数的函数方法。)

所以,摆脱这个错误很容易:

player.Check().check_all(tic_tac_toe_grid)

但是你几乎肯定想要做的事情就是在你需要的地方创建一个Check()实例。每个玩家都拥有一张支票吗?然后是这样的事情:

class Player:
    def __init__(self, counter): # initialize
        self.counter = counter # set player counter
        self.check = Check()

然后你可以使用它:

player.check.check_all(tic_tac_toe_grid)

我实际上并不知道你的对象模型应该是什么,但希望你这样做。

答案 1 :(得分:0)

CheckPlayer中的嵌套类,您可以使用Player.Check或使用Player个实例访问它 - 在您的情况下为player

嵌套类的行为与普通类的行为相同。它的方法仍然需要一个实例。方法的self参数告诉您它在实例上运行。如果您不需要该课程的任何州,您有两种选择:

  1. 将所有方法从Check移动到自己的模块,并将函数放在那里,不需要任何类。或...
  2. 将所有方法设为Check静态(@staticmethod)。这是一个反模式。