Потому что foo
и foo2
- это два разных экземпляра класса и подкласса.Даже если func
действительно является той же ссылкой между Foo
и Foo2
, после создания экземпляров классов связанные методы создаются на основе этих двух различных экземпляров, поэтомуадрес памяти больше не совпадает и не является одним и тем же объектом, даже если они выполняют одно и то же:
>>> foo = Foo()
>>> foo2 = Foo2()
>>> foo.func
<bound method Foo.func of <__main__.Foo object at 0x072623D0>>
>>> foo2.func
<bound method Foo.func of <__main__.Foo2 object at 0x07262AD0>> # notice the different object
Стоит отметить, что при изменении ссылки Foo.func
, Foo2.func
также изменится.Однако, если вы измените Foo2.func
, Foo.func
не изменится:
>>> Foo2.func
<function Foo.func at 0x0726B780>
>>> Foo.func
<function Foo.func at 0x0726B780>
>>> Foo.func = lambda: print("I'm new!")
>>> Foo.func
<function <lambda> at 0x0726B738>
>>> Foo2.func
<function <lambda> at 0x0726B738> # Follows the same reference
>>> Foo2.func = lambda: print("Some other func")
>>> Foo2.func
<function <lambda> at 0x0726B780> # New function
>>> Foo.func
<function <lambda> at 0x0726B738> # unchanged.
И затем, если вы добавите новые методы в Foo
, Foo2
также автоматически подберет его:
>>> Foo.func2 = lambda: print('hey!')
>>> Foo2.func2
<function <lambda> at 0x0726B7C8>
Но как только вы перезаписаете существующую ссылку унаследованного Foo.func
, даже если вы переназначите Foo.func
, Foo2.func
больше не будет содержать ту же ссылку:
>>> Foo.func = lambda: print("I'm renewed!")
>>> Foo.func
<function <lambda> at 0x0726B738> # newly assigned object
>>> Foo2.func
<function <lambda> at 0x0726B780> # Reference remains as before