有没有办法在 class 中使用 __str__ 但返回列表?

Is there a way to use __str__ in a class but returning a list?

当我调用 class 对象时,我希望它成为 return 列表或除字符串

之外的任何其他变量
class Vec:
    def __init__(self, data) -> None:
        self.data = data #THIS IS A LIST

    def __str__(self) -> list:
        return self.data

a = Vec([0,1,2,3])
print(a) 

#TypeError: __str__ returned non-string (type list)

相反,我得到一个 TypeError,如果我将“self.data”设置为一个字符串,它将起作用

有什么妙法吗?提前致谢

这里是完整的代码,以备不时之需

注意:我还没有完成它,我的问题是,例如,如果我想将 MatVec 相乘,我将不得不做 Mat * Vec.dataMat * Vec.T (T 代表转置)我不喜欢,我只想输入 Mat * Vec 以防我不需要转置向量。对不起,我的代码很乱,对我的问题的解释也很糟糕

class MatrixMatchError(Exception):
    def __init__(self):
        self.message = "Matrix sizes do not match"
        super().__init__(self.message)
    pass

class MatrixRowColError(Exception):
    def __init__(self):
        self.message = "The number of columns in the first matrix do not equal to the number of rows in the second."
        super().__init__(self.message)
    pass

class Vec:
    def __init__(self, x, identity=1) -> None:
        self.x = x
        self.data = self.Create(x, 1, identity)
        self.T = self.Transpose()

    def Create(self, x, y, identity) -> list:
        vec = []
        for i in range(y):
            vec.append([])
            for j in range(x):
                vec[i].append(identity)

        return vec

    def Transpose(self) -> list:
        vec = self.Create(len(self.data), len(self.data[0]), 0)
        for i in range(len(self.data)):
            for j in range(len(self.data[0])):
                vec[j][i] = self.data[i][j]

        return vec

class Mat:
    def __init__(self, x, y=0, identity=1) -> None:
        self.x = x
        if y == 0:
            self.y = x
        else:
            self.y = y

        self.data = self.Create(self.x, self.y, identity)
        self.T = self.Transpose()

    def __add__(self, data):
        if not self.CheckSize(data):
            raise MatrixMatchError

        mat3 = self.data.copy()
        for i in range(len(self.data)):
            for j in range(len(self.data[0])):
                mat3[i][j] = self.data[i][j] + data[i][j]

        return mat3

    def __sub__(self, data):
        if not self.CheckSize(data):
            raise MatrixMatchError

        mat3 = self.data.copy()
        for i in range(len(self.data)):
            for j in range(len(self.data[0])):
                mat3[i][j] = self.data[i][j] - data[i][j]

        return mat3

    def __mul__(self, data):
        if not self.CheckRowCol(data):
            raise MatrixRowColError

        mat3 = self.Create(len(data[0]), len(self.data),  0)

        for i in range(len(self.data)):
            for j in range(len(data[0])):
                for k in range(len(self.data[0])):
                    mat3[i][j] += self.data[i][k] * data[k][j]

        return mat3

    def Create(self, x, y, identity) -> list:
        mat = []
        for i in range(y):
            mat.append([])
            for j in range(x):
                mat[i].append(0)

        if x == y:
            for i in range(x):
                mat[i][i] = identity

        return mat

    def Transpose(self) -> list:
        mat = self.Create(len(self.data), len(self.data[0]), 0)
        for i in range(len(self.data)):
            for j in range(len(self.data[0])):
                mat[j][i] = self.data[i][j]

        return mat

    def CheckSize(self, data):
        if len(self.data) != len(data) or len(self.data[0]) != len(data[0]):
            return False
        return True

    def CheckRowCol(self, data):
        if len(data) != len(self.data[0]):
            return False
        return True

    def Transform(self):
        pass

    def Scale(self):
        pass

    def Rotate(self):
        pass
        

mat1 = Mat(2)
mat1.data = [[4,5, 4],
            [9,3, 7],
            [7,1, 3]]

vec = Vec(3)
print(mat1 * vec.T)

内置 str() 函数将引发 TypeError 如果它调用你的 __str__ 并得到不是字符串的东西,否则你不会说服它这样做.

您可能想要的是 Vec.__str__ 到 return data 的字符串表示,而不是 data 本身:

class Vec:
    def __init__(self, data: list) -> None:
        self.data = data

    def __str__(self) -> str:
        return str(self.data)

__str__ 方法与您的其他用例无关:

for example if I want to multiply Mat with a Vec I would have to do Mat * Vec.data or Mat * Vec.T (T stands for transposed) which I dont like and I would just like to type Mat * Vec in case I dont need to transpose the vector.

这应该在 Mat.__mul__ 中解决(它应该在 Vec 上运行,而不是底层 list)和 Vec.T/Vec.Transpose(应该 return 一个 Vec,而不是 list):

class Vec:

    ...

    def Transpose(self) -> 'Vec':
        vec = self.Create(len(self.data), len(self.data[0]), 0)
        for i in range(len(self.data)):
            for j in range(len(self.data[0])):
                vec[j][i] = self.data[i][j]
        return Vec(vec)


class Mat:
    ...

    def __mul__(self, vec: Vec) -> list[list[int]]:
        if not self.CheckRowCol(vec.data):
            raise MatrixRowColError

        mat3 = self.Create(len(vec.data[0]), len(self.data),  0)

        for i in range(len(self.data)):
            for j in range(len(vec.data[0])):
                for k in range(len(self.data[0])):
                    mat3[i][j] += self.data[i][k] * vec.data[k][j]

        return mat3

现在你确实可以做 Mat * VecMat * Vec.T,它会做正确的事情。

请注意,Mat.__mul__ 到 return 和 Mat 可能会更好,但您没有提供使我可以轻松实现该部分的构造函数 - - 尽管如此,我希望这能给你一个更好的方法来思考你的 class 界面,以及它们如何使 class 的使用变得更容易(或更难)!理想情况下 class 的用户甚至不应该 能够 访问内部结构,更不用说被迫访问了。

与此无关,我建议花一些时间学习 Python 的列表理解语法,因为它会为您节省大量列表分配样板(即您的各种 Create 方法)。 :)