类的循环导入

问题描述 投票:0回答:1

我是面向对象编程(和Python)的新手。为什么下面的代码是一个糟糕的对象设计?有什么好的设计不会导致这里的循环导入? 我希望这些类能够进行通信,但是在第二个内部使用第一个,反之亦然会导致 NameError: name 'Board' is not Defined。 或者这是 python 的问题并且使用不同的导入会有所帮助?

import numpy as np

class Coordinates:
    def __init__(self, col: int, row: int):
        self.__col = col
        self.__row = row

    def get_col(self):
        return self.__col

    def get_row(self):
        return self.__row

    def c_on_board(self, board: Board):
        existing = board.get_all_existing()
        return [self.__col, self.__row] in existing

class Board:
    def __init__(self, mat: np.matrix):
        self.__mat = mat

    def get_value(self, c: Coordinates):
        return self.__mat[c.get_col()][c.get_row()]

    def get_all_existing(self):
        A = np.array(self.__mat)
        existing = np.argwhere(A != np.nan)
        return existing

我尝试为这两个类创建单独的 .py 文件,并使用

from classes.board import Board
等导入它们,但问题仍然存在,只是这次它引发 ImportError:无法从部分初始化的模块 'classes.Board 导入名称 'Board' '(很可能是由于循环导入)

python oop nameerror
1个回答
0
投票

您看到的问题是您已将

Coordinates
类与
Board
类紧密耦合。 在编程中,我们希望避免耦合,因为对一个类的更改必须考虑到与其耦合的所有其他类。

当每个类独立于其他类时,管理代码(尤其是大型代码库)会容易得多。 让我们问一个问题“为什么坐标需要了解 Board”? 事实并非如此! 坐标仅包含行和列。 这就是它需要做的全部。

相反,我们可以将坐标是否有效的检查移至 Board 类。 如果坐标无效,您将引发错误以让用户知道发生了什么。

import numpy as np

class Coordinates:
    def __init__(self, col: int, row: int):
        self._col = col
        self._row = row

    def get_col(self):
        return self._col

    def get_row(self):
        return self._row


class Board:
    def __init__(self, mat: np.matrix):
        self._mat = mat

    def get_value(self, c: Coordinates):
        if not self._coord_is_in_board(c):
            raise ValueError('Coordinate is not within the Board boundaries')
        return self._mat[c.get_col()][c.get_row()]

    def get_all_existing(self):
        return np.argwhere(self._mat != np.nan)
    
    def _coord_is_in_board(self, c: Coordinates) -> False:
        n_rows, n_cols = self._mat.shape
        row_valid = (0 <= c.get_row() < n_rows)
        col_valid = (0 <= c.get_col() < n_cols)
        return row_valid and col_valid
© www.soinside.com 2019 - 2024. All rights reserved.