It is not directly possible to change a built in class, without going into a lot of trouble, check this post about the forbiddenfruit
repo.
However we can ofcourse inherit from the built-in and then manually overwrite the append
method.
Without more detail I am not sure if this minimal working examplee would solve your problem:
class MyList(list):
def append(self, value):
print('Mocked')
class Foo:
var = list()
var_filled = list([5, 6, 7, 8])
mock_foo_var = Foo.var
mock_foo_var = MyList(*mock_foo_var)
mock_foo_var.append(10)
mock_var_filled = Foo.var_filled
mock_var_filled = MyList(mock_var_filled)
mock_var_filled.append(10)
print(mock_foo_var)
print(mock_var_filled)
This would lead to the output:
Mocked
Mocked
[]
[5, 6, 7, 8]
Note that the value 10 is not added, but used to print the Mocked
output instead. You can change this behavior in any way you want.
Extra:
Maybe you do want to append a value, the easiest way to do that is by using insert
and len
def append(self, value):
self.insert(len(self), value)
print('Mocked')
If this is not what you were looking for, please update the question with more details.
Edit 1
Since we now have a new instance of MyList
we can also change the list
reference on the module level. You cannot change a method of list
, but you are allowed to rename the variable. So the following is also possible:
list = MyList
var = list()
var.append(10)
Which will result in the output:
Mocked
This reference will work if it is located in the same module (before list
is called).
Edit 2
While thinking about it for a bit longer, the use case is actually not that simple. There are 3 common ways of creating a list in python:
var = list()
var = []
var = list([])
The above described method will only work for the first and last case.
[] = list()
list = MyList
def test_case_1():
var = list()
var.append(10)
print("Passed test 1:", len(var) == 0)
def test_case_2():
var = list([])
var.append(10)
print("Passed test 2:", len(var) == 0)
def test_case_3():
var = list([1, 2, 3])
var.append(10)
print("Passed test 3:", len(var) == 3)
def test_case_4():
var = []
var.append(10)
print("Passed test 4:", len(var) == 0)
def test_case_5():
var = [1, 2, 3]
var.append(10)
print("Passed test 5:", len(var) == 3)
test_case_1()
test_case_2()
test_case_3()
test_case_4()
test_case_5()
Will result in the output:
Mocked
Passed test 1: True
Mocked
Passed test 2: True
Mocked
Passed test 3: True
Passed test 4: False
Passed test 5: False
The var
for test case 4 and 5 will contain:
[10]
[1, 2, 3, 10]
So when using this solution all lists have to be explicitly created using list()
, and cannot use the [ ]
list assignment.
If anybody knows how to override the [ ]
function, I would be interested to know how.