有没有办法在 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”设置为一个字符串,它将起作用
有什么妙法吗?提前致谢
这里是完整的代码,以备不时之需
注意:我还没有完成它,我的问题是,例如,如果我想将 Mat
与 Vec
相乘,我将不得不做 Mat * Vec.data
或 Mat * 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 * Vec
或 Mat * Vec.T
,它会做正确的事情。
请注意,Mat.__mul__
到 return 和 Mat
可能会更好,但您没有提供使我可以轻松实现该部分的构造函数 - - 尽管如此,我希望这能给你一个更好的方法来思考你的 class 界面,以及它们如何使 class 的使用变得更容易(或更难)!理想情况下 class 的用户甚至不应该 能够 访问内部结构,更不用说被迫访问了。
与此无关,我建议花一些时间学习 Python 的列表理解语法,因为它会为您节省大量列表分配样板(即您的各种 Create
方法)。 :)
当我调用 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”设置为一个字符串,它将起作用
有什么妙法吗?提前致谢
这里是完整的代码,以备不时之需
注意:我还没有完成它,我的问题是,例如,如果我想将 Mat
与 Vec
相乘,我将不得不做 Mat * Vec.data
或 Mat * 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 aVec
I would have to doMat * Vec.data
orMat * Vec.T
(T stands for transposed) which I dont like and I would just like to typeMat * 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 * Vec
或 Mat * Vec.T
,它会做正确的事情。
请注意,Mat.__mul__
到 return 和 Mat
可能会更好,但您没有提供使我可以轻松实现该部分的构造函数 - - 尽管如此,我希望这能给你一个更好的方法来思考你的 class 界面,以及它们如何使 class 的使用变得更容易(或更难)!理想情况下 class 的用户甚至不应该 能够 访问内部结构,更不用说被迫访问了。
与此无关,我建议花一些时间学习 Python 的列表理解语法,因为它会为您节省大量列表分配样板(即您的各种 Create
方法)。 :)