Reputation: 13
Currently if I input x = Matrix([[5, 4], [3, 8]])
it is calling __str__
. How do I get it to call another method with this input?
class Matrix(object):
def __init__(self, matrix = 0):
self.matrix = matrix
def __Matrix__(self):
return 10
def __str__(self):
return "\\n".join(["\\t".join
(["%d" % k for k in row]) for row in self.matrix])
If my input is x = Matrix([[5, 4], [3, 8]])
how do I tell the program to call the method __Matrix__
? It is currently calling __str__
.
I tried to make a method "Matrix" inside the class "Matrix", but the program didn't change, it keeps using the __str__
method.
Upvotes: 0
Views: 70
Reputation: 55469
Python has no way of knowing that it's supposed to use your __Matrix__
method to print a Matrix instance. The way that special method names are handled is an internal language feature, you can't just add new special method names or change the way existing ones are handled without modifying the Python source and compiling your own version. And it's generally not a good idea to do that unless you really need to. ;)
As I mentioned above, __str__
should return a string that's suitable to display to the user, so it's probably not a good idea to return that sequence containing '\\t'
and '\\n'
via __str__
. I guess you could return it via __repr__
, but that's still a little odd, IMHO. I strongly suggest that you give it a new name, like esc_str
.
Just for fun, I've implemented a relatively simple __format__
method for you class. This special method gets called by the format
built-in function and the str.format
method. It also gets called by the new f-string syntax.
My __format__
method determines the minimum width required for each column of the matrix, you can supply a numeric format_spec to set a minimum width for all columns. An extra space is added to stop columns running together. You could enhance this method to handle an initial '>' or '<' in the format_spec to indicate alignment.
class Matrix(object):
def __init__(self, matrix = 0):
self.matrix = matrix
def __format__(self, minwidth):
minwidth = int(minwidth) if minwidth else 0
# Find maximum width of each column
widths = [max(len(str(k)) for k in col) for col in zip(*self.matrix)]
widths = [max(minwidth, u) for u in widths]
result = []
for row in self.matrix:
result.append(" ".join(["%*d" % t for t in zip(widths, row)]))
return "\n".join(result)
def __repr__(self):
return "Matrix(%s)" % self.matrix
def __str__(self):
return "\n".join(["\t".join(["%d" % k for k in row])
for row in self.matrix])
def esc_str(self):
return r"\n".join([r"\t".join(["%d" % k for k in row])
for row in self.matrix])
# test
m = Matrix([[1, 2, 3], [5, 4, 16], [9, 867, 0]])
print(repr(m))
print(m)
print(m.esc_str())
print('Matrix\n{:2}'.format(m))
print(f'Matrix\n{m}')
output
Matrix([[1, 2, 3], [5, 4, 16], [9, 867, 0]])
1 2 3
5 4 16
9 867 0
1\t2\t3\n5\t4\t16\n9\t867\t0
Matrix
1 2 3
5 4 16
9 867 0
Matrix
1 2 3
5 4 16
9 867 0
Upvotes: 1
Reputation: 51
you can just call the function
print(x.__Matrix__())
and it should work if you just print the object it automatically call the built in function str
Upvotes: 0