It is not because of the extend itself: but because you use *args (with asterisk *). Indeed if you call:
Matrix([[0,0],[0,0]])
what will happen is that args is a tuple ([[0,0],[0,0]],) (with one element). So you extend the tuple and thus append the single element of the tuple: you append([[0,0],[0,0]]).
What you probably want is to extend all elements of args one-by-one, so:
class Matrix:
def __init__(self,*args):
self.m = []
for argi in args:
self.m.extend(argi)
In case you want to accept only one parameter, you can simplify the process into:
class Matrix:
def __init__(self,data): # without asterisk
self.m = []
self.m.extend(data)
Or make it more elegant, like:
class Matrix:
def __init__(self,data):
self.m = list(data)
Note that you make a shallow copy: you better make a deep copy since otherwise the rows will still be the same and thus modifications to the rows in one matrix will reflect on the other matrix. So:
from copy import deepcopy
class Matrix:
def __init__(self,data):
self.m = deepcopy(data)