从同一个类调用一个方法

时间:2011-02-17 01:54:38

标签: python class

我正在为一个连续4的简单游戏编写一个类,但是我遇到了在同一个类中调用方法的问题。为了完整起见,这是全班:

class Grid:
    grid = None
    # creates a new empty 10 x 10 grid
    def reset():
        Grid.grid = [[0] * 10 for i in range(10)]
    # places an X or O
    def place(player,x,y):
        Grid.grid[x][y] = player
    # returns the element in the grid
    def getAt(x,y):
        return Grid.grid[x][y]
    # checks for wins in a certain direction
    def checkLine(player,v,count,x,y):
        x = x+v[0]
        y = y+v[1]
        if x < 0 or x > 9:
            return
        if y < 0 or y > 9:
            return
        if Grid.grid[x][y] == p:
            count = count+1
            if count == 4:
                return True
            checkLine(player,v,count,x,y)
        return False
    # returns the number of the player that won
    def check():
        i = 'i'
        for x in range(0,10):
            for y in range(0,10):
                if Grid.grid[x][y] > 0:
                    p = Grid.grid[x][y]
                    f = checkLine(p,0,array(i,[1,0]),x,y)
                    if f:
                        return p
                    f = checkLine(p,0,array(i,[0,1]),x,y)
                    if f:
                        return p
                    f = checkLine(p,0,array(i,[1,1]),x,y)
                    if f:
                        return p
                    f = checkLine(p,0,array(i,[-1,0]),x,y)
                    if f:
                        return p
                    f = checkLine(p,0,array(i,[0,-1]),x,y)
                    if f:
                        return p
                    f = checkLine(p,0,array(i,[-1,-1]),x,y)
                    if f:
                        return p
                    f = checkLine(p,0,array(i,[1,-1]),x,y)
                    if f:
                        return p
                    f = checkLine(p,0,array(i,[-1,1]),x,y)
                    if f:
                        return p
        return 0
    reset = staticmethod(reset)
    place = staticmethod(place)
    getAt = staticmethod(getAt)
    check = staticmethod(check)
    checkLine = staticmethod(checkLine)

我正在尝试从check()调用checkLine(),但是我收到错误“ NameError:全局名称'checkLine'未定义”。当我调用Grid.checkLine()时,我得到“ TypeError:'模块'对象不可调用

如何调用checkLine()?

编辑:

@beer_monk

class Grid(object):
    grid = None
    # creates a new empty 10 x 10 grid
    def reset(self):
        Grid.grid = [[0] * 10 for i in range(10)]
    # places an X or O
    def place(self,player,x,y):
        Grid.grid[x][y] = player
    # returns the element in the grid
    def getAt(self,x,y):
        return Grid.grid[x][y]
    # checks for wins in a certain direction
    def checkLine(self,player,v,count,x,y):
        x = x+v[0]
        y = y+v[1]
        if x < 0 or x > 9:
            return
        if y < 0 or y > 9:
            return
        if Grid.grid[x][y] == p:
            count = count+1
            if count == 4:
                return True
            checkLine(self,player,v,count,x,y)
        return False
    # returns the number of the player that won
    def check(self):
        i = 'i'
        for x in range(0,10):
            for y in range(0,10):
                if Grid.grid[x][y] > 0:
                    p = Grid.grid[x][y]
                    for vx in range(-1,2):
                        for vy in range(-1,2):
                            f = self.checkLine(p,0,array(i,[vx,vy]),x,y)
                            if f:
                                return p
        return 0
    reset = staticmethod(reset)
    place = staticmethod(place)
    getAt = staticmethod(getAt)
    check = staticmethod(check)
    checkLine = staticmethod(checkLine)

7 个答案:

答案 0 :(得分:8)

摆脱课堂。对grid使用普通函数和模块级变量。 课程没有以任何方式帮助你。

PS。如果您真的想在课堂上拨打checkline,请拨打Grid.checkline。例如:

class Foo:
    @staticmethod
    def test():
        print('Hi')
    @staticmethod
    def test2():
        Foo.test()

Foo.test2()       

打印

Hi

答案 1 :(得分:1)

<强>语法:

class_Name.function_Name(self)

示例:

Turn.checkHoriz(self)

答案 2 :(得分:0)

与java或c ++不同,在python中,所有类方法都必须接受类实例作为第一个变量。在我见过的每一个python代码中,该对象被称为self。例如:

def reset(self):
    self.grid = [[0] * 10 for i in range(10)]

请参阅http://docs.python.org/tutorial/classes.html

请注意,在其他语言中,翻译是自动进行的

答案 3 :(得分:0)

您实际上是在修改类本身,而不是对某个对象进行操作。 Python允许你这样做,但它不是真正的类。所以你遇到了几个问题

- 你永远无法以这种方式制作多个网格

  • 网格无法返回自身,例如致电checkLine

在网格定义之后,尝试实例化网格并像这样调用方法

aGrid = Grid()
...
aGrid.checkLine()

要做到这一点,首先需要修改所有方法定义,将“self”作为第一个变量,并在检查中调用self.checkLine()

def check(self):
    ...
    self.checkLine()
    ...

此外,您的重复检查会呼叫FOR循环。你不需要写出案例。

答案 4 :(得分:0)

您的班级定义中存在多个问题。您尚未定义在代码中使用的数组。同样在checkLine调用中,您正在发送一个int,并且在其定义中,您正在尝试下标它。抛开这些,我希望你意识到你在这里使用静态方法来处理所有的类方法。在这种情况下,无论何时在类中调用方法,您仍然需要通过类的类对象调用它们。因此,在您的课程中,当您致电 checkLine 时,请将其称为 Grid.checkLine 这应解决您的NameError问题。

此外,您的模块导入看起来有些问题。您可能已经按名称Grid导入了一个Module,并且您也有一个名为Grid的类。 Python认为您正在调用导入的模块Grid方法,该方法不可调用。 (我认为,这里没有完整的图片可以看出为什么会产生TypeError)

解决问题的最佳方法是使用最好使用的类,即在这些对象上创建对象和调用方法。还使用适当的命名空间。对于所有这些,您可以从一些很好的介绍性材料开始,比如Python教程。

答案 5 :(得分:0)

一个重做的例子(希望能更好地使用类!)

import itertools

try:
    rng = xrange   # Python 2.x
except NameError:
    rng = range    # Python 3.x

class Turn(object):
    def __init__(self, players):
        self.players = itertools.cycle(players)
        self.next()

    def __call__(self):
        return self.now

    def next(self):
        self.now = self.players.next()

class Grid(object):
    EMPTY = ' '
    WIDTH = 10
    HEIGHT = 10
    WINLENGTH = 4

    def __init__(self, debug=False):
        self.debug = debug
        self.grid = [Grid.EMPTY*Grid.WIDTH for i in rng(Grid.HEIGHT)]
        self.player = Turn(['X','O'])

    def set(self, x, y):
        if self.grid[y][x]==Grid.EMPTY:
            t = self.grid[y]
            self.grid[y] = t[:x] + self.player() + t[x+1:]
            self.player.next()
        else:
            raise ValueError('({0},{1}) is already taken'.format(x,y))

    def get(self, x, y):
        return self.grid[y][x]

    def __str__(self):
        corner = '+'
        hor = '='
        ver = '|'
        res = [corner + hor*Grid.WIDTH + corner]
        for row in self.grid[::-1]:
            res.append(ver + row + ver)
        res.append(corner + hor*Grid.WIDTH + corner)
        return '\n'.join(res)

    def _check(self, s):
        if self.debug: print("Check '{0}'".format(s))
        # Exercise left to you!
        # See if a winning string exists in s
        # If so, return winning player char; else False
        return False

    def _checkVert(self):
        if self.debug: print("Check verticals")
        for x in rng(Grid.WIDTH):
            winner = self._check([self.get(x,y) for y in rng(Grid.HEIGHT)])
            if winner:
                return winner
        return False

    def _checkHoriz(self):
        if self.debug: print("Check horizontals")
        for y in rng(Grid.HEIGHT):
            winner = self._check([self.get(x,y) for x in rng(Grid.WIDTH)])
            if winner:
                return winner
        return False

    def _checkUpdiag(self):
        if self.debug: print("Check up-diagonals")
        for y in rng(Grid.HEIGHT-Grid.WINLENGTH+1):
            winner = self._check([self.get(d,y+d) for d in rng(min(Grid.HEIGHT-y, Grid.WIDTH))])
            if winner:
                return winner
        for x in rng(1, Grid.WIDTH-Grid.WINLENGTH+1):
            winner = self._check([self.get(x+d,d) for d in rng(min(Grid.WIDTH-x, Grid.HEIGHT))])
            if winner:
                return winner
        return False

    def _checkDowndiag(self):
        if self.debug: print("Check down-diagonals")
        for y in rng(Grid.WINLENGTH-1, Grid.HEIGHT):
            winner = self._check([self.get(d,y-d) for d in rng(min(y+1, Grid.WIDTH))])
            if winner:
                return winner
        for x in rng(1, Grid.WIDTH-Grid.WINLENGTH+1):
            winner = self._check([self.get(x+d,d) for d in rng(min(Grid.WIDTH-x, Grid.HEIGHT))])
            if winner:
                return winner
        return False

    def isWin(self):
        "Return winning player or False"
        return self._checkVert() or self._checkHoriz() or self._checkUpdiag() or self._checkDowndiag()

def test():
    g = Grid()
    for o in rng(Grid.WIDTH-1):
        g.set(0,o)
        g.set(Grid.WIDTH-1-o,0)
        g.set(Grid.WIDTH-1,Grid.HEIGHT-1-o)
        g.set(o,Grid.HEIGHT-1)
    print(g)
    return g

g = test()
print g.isWin()

答案 6 :(得分:0)

Java程序员以及以下是我如何调用内部方法:

class Foo:
    variable = 0

    def test(self):
        self.variable = 'Hi'
        print(self.variable)

    def test2(self):
        Foo.test(self)

tmp = Foo()
tmp.test2()