Одно из различий 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», тогда, должно быть, всё более-менее встаёт на свои места.
14 марта 2011 00:12

zero_sharp (инкогнито)
14 марта 2011, 01:22

Вы просто не умеете правильно питон готовить.
Любой нормальный программист на питоне знает, что чем чаще в коде повторяется знак подчёркивания, тем код объектно-ориентированней.
В вашем случае достаточно сделать так:

b.show = A.__dict__['show'].__get__(b, B)

И всё заработает, как в яваскрипте.

bolk (bolknote.ru)
14 марта 2011, 01:34, ответ предназначен zero_sharp

Вы какой-то странный вывод из моего рассказа сделали.

В рассказе не было ничего про то, что я не могу вызвать метод в другом контексте, там было про различия поведения похожего по смыслу кода в разных языках.

zero_sharp (инкогнито)
14 марта 2011, 01:39

On a totally different note, подобное присваивание методов в питоне мне кажется дурным тоном.
Чего Вы хотите подобным кодом добиться в обоих случаях? «Пересадки» методов? В питоне для этого есть классы и наследование.

bolk (bolknote.ru)
14 марта 2011, 01:49, ответ предназначен zero_sharp

Ну и, кстати, почему не

b.show = a.show.__func__.__get__(b, b.__class__)

bolk (bolknote.ru)
14 марта 2011, 01:55, ответ предназначен zero_sharp

On a totally different note, подобное присваивание методов в питоне мне кажется дурным тоном.
Вы упорно пытаетесь что-то додумать к заметке. Это не какой-то реальный код приложения, а иллюстрация различий.

Ничего страшного, кстати, в таком переносе функционала нет. Обычное «подмешивание» методов, просто у Пайтона этот функционал никак особо не выделен, но это ещё не значит, что его нельзя применять.

bolk (bolknote.ru)
14 марта 2011, 01:58, ответ предназначен zero_sharp

Под «подмешиванием» я имею ввиду то, что обычно называется «traits» или «method mix-in».

bolk (bolknote.ru)
14 марта 2011, 02:06, ответ предназначен zero_sharp

Если хочется более-менее реального кода, а не чистой демонстрации, то будет что-то вроде следующего.

JS:
var method = expr ? a.show : b.show


method()

Python:
method = a.show if expr else b.show


method()

Результат будет сильно разный.

Азат Разетдинов (razetdinov.ya.ru)
14 марта 2011, 07:19

В ES5 для сохранения контекста появился .bind():
b.show = a.show.bind(b)

bolk (bolknote.ru)
14 марта 2011, 09:27, ответ предназначен Азат Разетдинов (razetdinov.ya.ru):

Я знаю, Азат, спасибо! :)

Ivan (инкогнито)
14 июня 2016, 23:18

А не подскажите, с какого языка начать изучение программирования с JS или Python? Цель - легче заработать денег, а то в моей отрасле больше чем я зарабатываю очень сложно достичь.

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)