This is a scope issue. Within test the variable a, b are local references to objects a and b outside of test. Thus a and b in the context of test can be named anything.
Here's the code with some printouts that'll help explain this better:
def test(test_b, test_a):
print('test_a references object in memory {} with values {}'.format(id(test_a), test_a))
print('append(10)')
test_a.append(10)
print('test_a references object in memory {} with values {}'.format(id(test_a), test_a))
print('assign reference test_a = test_b # new value {}'.format(id(test_b)))
test_a = test_b
print('test_a references object in memory {} with values {}'.format(id(test_a), test_a))
outside_a = [1, 2, 3]
outside_b = [4, 5, 6]
test(outside_b, outside_a)
print('outside_a references object in memory {} with values {}'.format(id(outside_a), outside_a))
A sample output of this would be like:
test_a references object in memory 140058884752448 with values [1, 2, 3]
append(10)
test_a references object in memory 140058884752448 with values [1, 2, 3, 10]
assign reference test_a = test_b # new value 140058887943936
test_a references object in memory 140058887943936 with values [4, 5, 6]
outside_a references object in memory 140058884752448 with values [1, 2, 3, 10]