Одно из различий Python и JavaScript
Чем дальше, тем между большим количеством языков программирования мне приходится переключаться. Одно из различий объектной модели Пайтона и ДжаваСкрипта мне портит кровь (у них парадигмы ООП вообще сильно различаются), если я вовремя не соображу, что надо переключиться с одного языка на другой.
Суть в том, что в Пайтоне метод ходит в гости со своим контекстом:
class A:
test = 'A'
def show(self): print self.test
class B: test = 'B'
a, b = A(), B()
show = a.show
b.show = a.show
show() # A
b.show() # AТогда как в JavaScript такой код будет работать совершенно иначе, там методы в чужой монастырь со своим уставом не ходят (если их не попросить):
var test = 'global';
A = function () {
this.test = 'A',
this.show = function () { alert(this.test) }
};
B = function () { this.test = 'B'; }
a = new A(); b = new B();
b.show = a.show
show = a.show
show() // global
b.show() // B
b.show.apply(a) // AПоявление «global» наверное надо разъяснить тем, кто JS знает плохо. На самом деле первая строчка (в данном случае) может читаться как «window.test = ’global’», а «show = a.show» как «window.show = a.show», тогда, должно быть, всё
Комментарии 10
Любой нормальный программист на питоне знает, что чем чаще в коде повторяется знак подчёркивания, тем код
В вашем случае достаточно сделать так:
b.show = A.__dict__['show'].__get__(b, B)
И всё заработает, как в яваскрипте.
В рассказе не было ничего про то, что я не могу вызвать метод в другом контексте, там было про различия поведения похожего по смыслу кода в разных языках.
Чего Вы хотите подобным кодом добиться в обоих случаях? «Пересадки» методов? В питоне для этого есть классы и наследование.
Ну и, кстати, почему не
b.show = a.show.__func__.__get__(b, b.__class__)
Комментарий для zero_sharp:
Вы упорно пытаетесьчто-то додумать к заметке. Это не какой-то реальный код приложения, а иллюстрация различий.
Ничего страшного, кстати, в таком переносе функционала нет. Обычное «подмешивание» методов, просто у Пайтона этот функционал никак особо не выделен, но это ещё не значит, что его нельзя применять.
Под «подмешиванием» я имею ввиду то, что обычно называется «traits» или «method
Если хочется
JS:
var method = expr ? a.show : b.show
…
…
method()
Python:
method = a.show if expr else b.show
…
…
method()
Результат будет сильно разный.
b.show = a.show.bind(b)