user9098464
user9098464

Reputation: 13

Using several methods inside class

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

Answers (2)

PM 2Ring
PM 2Ring

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

ayoub aboussaad
ayoub aboussaad

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

Related Questions