A beginner's first Tic Tac Toe implementation
Visuals
You can try
self.values = [[&quot;-&quot; for _ in range(3)] for _ in range(3)]

This will let you set up a 3x3 grid without having to draw the whole thing.
Now you can also do
    def show_board(self):
        board_str = &quot;\n&quot;.join([ &quot; | &quot;.join(row) for row in grid ])
        print(board_str)

I would also suggest doing away with the show_board function altogether and instead use (for printing)
    def __str__(self):
        return &quot;\n&quot;.join([ &quot; | &quot;.join(row) for row in grid ])

and/or (for printing in interactive console)
    def __repr__(self):
        return &quot;\n&quot;.join([ &quot; | &quot;.join(row) for row in grid ])

Then you can directly do
xoxo = TicTacToe
print(xoxo)

and inside the class
print(self)

Data Representation and Input
I'm repeating myself here, but it doesn't make sense to have values be a 1-dimensional array. It's a tic-tac-toe board... it should be a 2D 3x3 grid or board. Also you should probably rename the variable values to grid or board.
This will mean taking 2 values as input from user in handle_turn(). I suggest not putting a large string inside input() as it's hard to read. Try instead
print(&quot;Enter space separated co-ordinates to pick a square&quot;)
print(f&quot;Player {self.player} pick a square: &quot;))
x = int(input())
y = int(input())

Ok, I'll admit this is a little annoying for the players.... maybe you could write the coordinates in the empty cells like
 X  | 1,2 |  O
2,1 |  X  | 1,3
3,1 | 3,2 |  O

(try to do this without writing out the whole starting grid manually, it should be possible using &quot;,&quot;.join(), str() and list comprehensions)
Also it should be possible to modify the row/column/diagonals functions with 2D indices like grid[0][0], grid[1][1], grid[2][2], etc. to make it more readable. Due to the way self.grid is stored, the row function can be simplified... but it will look very different from column/diagonal and so it's probably not worth it.