>>> (1).__str__!=(2).__str__
True
Is there any technical reason why they've been made seperate objects instead of refering to a single object? It seems like it would be more efficient
That is because you don't get the __str__
function, but a method wrapper for it.
>>> x = (1).__str__
>>> type(x)
<class 'method-wrapper'>
>>> x()
'1'
>>> x.__self__
1
>>> x = (2).__str__
>>> x()
'2'
>>> x.__self__
2
A method wrapper is an object that keeps a reference to self
. So it has to be different for every instance.
For more details, check this question.