Уведомления

Группа в Telegram: присоединиться | Jabber-конференция сообщества: pythonua@conference.jabber.ru

#1 Июнь 6, 2007 20:32:12

pento
От:
Зарегистрирован: 2007-05-29
Сообщения: 100
Репутация: +  0  -
Профиль   Отправить e-mail  

В чём тайный смысл в передаче методу класса self?

Просто интересует логика рзработчиков языка..зачем каждый раз в методе класса передавать self?
Почему нет аналога this-> ?
Или может я просто не просёк всей фишки?
Поясните, пжста.



Офлайн

#2 Июнь 6, 2007 22:28:35

Maximbo
От:
Зарегистрирован: 2006-11-04
Сообщения: 137
Репутация: +  0  -
Профиль   Отправить e-mail  

В чём тайный смысл в передаче методу класса self?

Возможно, “Явное лучше неявного” © ;)



Офлайн

#3 Июнь 6, 2007 22:42:48

tabajara
От:
Зарегистрирован: 2007-01-02
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

В чём тайный смысл в передаче методу класса self?

>>> import this



Офлайн

#4 Июнь 7, 2007 08:59:51

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

В чём тайный смысл в передаче методу класса self?

pento
Просто интересует логика рзработчиков языка..зачем каждый раз в методе класса передавать self?
Почему нет аналога this-> ?
Или может я просто не просёк всей фишки?
Поясните, пжста.
Еще один…
Читайте про пространства имен в питоне. Потом подумайте еще раз над своим вопросом.
Это не фишка – это дизайн языка.



Отредактировано (Июнь 7, 2007 09:00:52)

Офлайн

#5 Июнь 7, 2007 09:03:15

asv13
От:
Зарегистрирован: 2007-01-22
Сообщения: 130
Репутация: +  0  -
Профиль   Отправить e-mail  

В чём тайный смысл в передаче методу класса self?

хорошо бы было от него избавиться
а то запись формул в функциях внутри класса получается неудобной
16e8 * self.Tres**(-2.8177) * log(self.API)**(5.7526 * log(self.Tres) - 26.9718)
и от self-а начинает рябить в глазах



Офлайн

#6 Июнь 7, 2007 10:29:20

Maximbo
От:
Зарегистрирован: 2006-11-04
Сообщения: 137
Репутация: +  0  -
Профиль   Отправить e-mail  

В чём тайный смысл в передаче методу класса self?

Это уже явный флейм. Господа, желающие продолжения банкета, могут проследовать в курилку.



Офлайн

#7 Июнь 7, 2007 12:57:24

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

В чём тайный смысл в передаче методу класса self?

Флейм - не флейм…
Я попытаюсь рассказать, как таки оно работает.

Когда пишем
class A(object):
def f(self):
print ‘A.f’, self

Класс A создается метаклассом type(name, bases, attrs)

>>>def f(self):
>>> print ‘A.f’, self
>>> A = type('A'), (object,), {'f':f})
<class ‘__main__’.A>
Все, что попадает в attrs - перечисленные внутри аттрибуты (функции и переменные класса). Когда type создает A, он проходит по словарю аттрибутов. Если элемент словаря - функция, то она вставляется через method дескриптор. Остальные аттрибуты не модифицируются.

Дескриптор - это специальный объект с методами __get__, __set__, __delete__. Для method descriptor достаточно __get__.
Если method дескриптор вызывается с инстанцией класса - получается bound method, с классом - unbound method
>>> a = A()
>>> a.f()
A.f <__main__.A object at 0x00D9A2D0>
>>> A.f
<unbound method A.f>
>>>

unbound method работает без сюрпризов, только всегда проверяет первый агумент на isinstance(<first argument>, A):
>>> A.f()
Traceback (most recent call last):
File “<interactive input>”, line 1, in ?
TypeError: unbound method f() must be called with A instance as first argument (got nothing instead)
>>> A.f(a)
A.f <__main__.A object at 0x00D9A2D0>
>>>

bound method немного сложнее:
>>> af = a.f
>>> af
<bound method A.f of <__main__.A object at 0x00D9A2D0>>
>>> af()
A.f <__main__.A object at 0x00D9A2D0>
Т.е. он запоминает в себе a и при вызове добавляет его как первый параметр (обычно это self)

В итоге получаем - методы по сути обычные функции, завернутые через дескрипторы, чтобы казались методами.
Помимо простоты и однозначности (def ВСЕГДА определяет свободную функцию), отсутствия необходимости в новом ключевом слове defmethod или серьезного усложнения обработки def, требующего знания о контекстах более высокого уровня (класса, модуля) мы с таким подходом еще и получаем очень гибкий механизм создания/изменения класса “на лету”.

С моей точки зрения, все вышеперечисленное вполне способно объяснить необходимость писать self. Вспомните еще про staticmethod, в котором self отсутствует, classmethod без self зато с cls - все они делаются через декораторы, создающие специализированные дескрипторы.
В соседней теме finite state machine на Питоне я приводил пример дескриптора, который выбирает реализацию функции основываясь на внутреннем состоянии.

Ну и конечно:
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Special cases aren't special enough to break the rules.



Отредактировано (Июнь 7, 2007 21:26:12)

Офлайн

#8 Июнь 7, 2007 14:16:25

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

В чём тайный смысл в передаче методу класса self?

К цитируемому Zen of Python добавлю последнюю мантру:

Namespaces are one honking great idea – let's do more of those!



Офлайн

#9 Июнь 7, 2007 14:18:45

bialix
От:
Зарегистрирован: 2006-07-13
Сообщения: 774
Репутация: +  1  -
Профиль   Отправить e-mail  

В чём тайный смысл в передаче методу класса self?

Здесь мелкая неточность:

с bound method все немного сложнее:
>>> af = a.f()
>>> af
<bound method A.f of <__main__.A object at 0x00D9A2D0>>

Должно быть

>>> af = a.f



Офлайн

#10 Июнь 7, 2007 14:28:51

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

В чём тайный смысл в передаче методу класса self?

bialix
Здесь мелкая неточность:

с bound method все немного сложнее:
>>> af = a.f()
>>> af
<bound method A.f of <__main__.A object at 0x00D9A2D0>>

Должно быть

>>> af = a.f
поправил



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version