为什么我无法访问另一个类中全局定义的类的实例?

时间:2016-05-12 18:58:32

标签: python class oop scope global-variables

我正在尝试使用Pawn类中的 ui 对象,我在所有内容之外定义并启动 ui ,所以它是全局的吗?我在这里查看了有关在类之外使用变量的问题,但它们似乎都引用了我在启动Chess对象时在UI类中使用的.self。

代表我为帮助提高可读性而编写的一些代码。

class UI:
    def ___init__(self):
        self.chess = Chess()
        # Calls main menu function which goes to a new game option

    def newGame(self):
        self.chess.startGame()
        while len(self.chess.pieces[0] == 2): # Which is index for Kings
            # Game, which is where *move* is called

class Chess:
    def startGame(self):
        self.chessBoard = Grid(9,9)
        self.pieces = []
        self.pawns = []
        for i in range(8):
            self.pawns.append(PawnObject(x,y,side))
        self.pieces.append(self.pawns)

class Grid:

    # Init method

    def cellOccupied(self,x,y):
        # This function checks if a place is empty
        # If empty, return false else, true

class Object:
    # Sets x, y, width, height


class ChessPiece:
    # Child of Object sets side (black or white)

class PawnObject:
    def move(self,newX,newY):
        if ui.chess.chessBoard.cellOccupied(newX,newY) == False:
            # Move

        # More code

ui = UI()

追溯:https://gyazo.com/33e5b37b5290ff88433b29874c117ad7

我做了一件令人眼花缭乱的错事吗?我认为我编程这一切的方式非常低效,因为我还在学习,所以这是结果吗?谢谢。

2 个答案:

答案 0 :(得分:1)

问题是这个级联事件系列都发生在UI的初始化函数中;一个类在原__init__有机会返回之前调用下一个类。这意味着执行初始化的行尚未完成,因此ui变量尚不存在

您应该尝试将其中的一部分移出该级联。特别是,由于初始化UI类,我无法理解为什么典当应该移动;这似乎没有任何意义。

您还应该考虑为什么需要ui成为全局变量;似乎更有可能它应该是其中一个类的属性,也许是Grid,并且pawn可以通过该实例引用它。

答案 1 :(得分:0)

你可能在类的主体中使用ui,这是在解释器看到类时(因此在ui存在之前)执行的。您只能在方法或函数中使用它,因为它们仅在被调用时执行。换句话说:

class UI:
    def open(self):
        pass

class Chess:
    ui.open()  # <--- this causes an error because it happens before the last line does
    def startGame(self):
        ui.open()   # <--- this is OK

ui = UI()

另外,我认为您的消息表明您在某个地方写了global ui,只有在您计划为ui分配新值时才需要ui = somethingui.open()。如果您只想使用它,例如chessBoard = Grid(9,9) ,您不需要全球声明。但删除它不会解决您的问题。

您还需要更正

self.chessBoard = Grid(9,9)

chessBoard

使Chess成为ui.chess.chessBoard的属性,您需要能够说InStr("E-","E")