You need to be very careful when using mutable default arguments. Please see “Least Astonishment” and the Mutable Default Argument. 
The reason for the difference in behaviour is that 
path = path + [node1]
creates a new list and binds it to the name path. The other 2 alternatives modify the existing list bound to path.
As the linked question explains, default arguments are created when the function definition is compiled, not when the function is called. This is especially significant when using a mutable default arg in a recursive function because it implies that the default arg is not reset on each top-level recursive call.
If you don't want the "special" behaviour that using a mutable default arg gives you, you can do something like:
def find_path(self, node1, node2, path=None):
    if path is None:
        path = []
    # rest of code
If None is a valid arg for path then you'll need to use some other sentinel, eg
sentinel = object()
def find_path(self, node1, node2, path=sentinel):
    if path is sentinel:
        path = []
    # rest of code
Here's a short demo that illustrates the "special" behaviour of a mutable default arg. You can see that lst remembers its previous contents.
def test(a, lst=[]):
    lst += [a]
    print(a, lst)
for i in range(5):
    test(i)
output
0 [0]
1 [0, 1]
2 [0, 1, 2]
3 [0, 1, 2, 3]
4 [0, 1, 2, 3, 4]
In contrast, using lst = lst + [a], we create a new list rather than appending to the default list.
def test(a, lst=[]):
    lst = lst + [a]
    print(a, lst)
for i in range(5):
    test(i)
output
0 [0]
1 [1]
2 [2]
3 [3]
4 [4]