Одно из различий 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», тогда, должно быть, всё более-менее встаёт на свои места.
Вы просто не умеете правильно питон готовить.
Любой нормальный программист на питоне знает, что чем чаще в коде повторяется знак подчёркивания, тем код объектно-ориентированней.
В вашем случае достаточно сделать так:
b.show = A.__dict__[’show’].__get__(b, B)
И всё заработает, как в яваскрипте.
Комментарий для zero_sharp:
Вы какой-то странный вывод из моего рассказа сделали.
В рассказе не было ничего про то, что я не могу вызвать метод в другом контексте, там было про различия поведения похожего по смыслу кода в разных языках.
On a totally different note, подобное присваивание методов в питоне мне кажется дурным тоном.
Чего Вы хотите подобным кодом добиться в обоих случаях? «Пересадки» методов? В питоне для этого есть классы и наследование.
Комментарий для zero_sharp:
Ну и, кстати, почему не
b.show = a.show.__func__.__get__(b, b.__class__)
Комментарий для zero_sharp:
Вы упорно пытаетесь что-то додумать к заметке. Это не какой-то реальный код приложения, а иллюстрация различий.
Ничего страшного, кстати, в таком переносе функционала нет. Обычное «подмешивание» методов, просто у Пайтона этот функционал никак особо не выделен, но это ещё не значит, что его нельзя применять.
Комментарий для zero_sharp:
Под «подмешиванием» я имею ввиду то, что обычно называется «traits» или «method mix-in».
Комментарий для zero_sharp:
Если хочется более-менее реального кода, а не чистой демонстрации, то будет что-то вроде следующего.
JS:
var method = expr ? a.show : b.show
…
…
method()
Python:
method = a.show if expr else b.show
…
…
method()
Результат будет сильно разный.
В ES5 для сохранения контекста появился .bind():
b.show = a.show.bind(b)
Комментарий для razetdinov.ya.ru:
Я знаю, Азат, спасибо! :)
А не подскажите, с какого языка начать изучение программирования с JS или Python? Цель — легче заработать денег, а то в моей отрасле больше чем я зарабатываю очень сложно достичь.