LINUX.ORG.RU

Python 2.2.2


0

0

This being a bug-fix release, there have been no exciting new features implemented since 2.2.1 -- just heaps of fixes.

With special dispensation from the "bugfixes only" rule, a brand new version of the email package (nee mimelib) is also included: email 2.4.3.

For a partial list of these fixes, please see the release notes, or the Misc/NEWS file in the source distribution. For the full list of changes, you can poke around CVS.

>>> release notes

★★★☆

Я не знаком с питоном к сожалению, поэтому для продолжения беседы хочу узнать как ведет себя класс определенный указаным вами способом при наследовании. Тоесть как наследник видит этот метод? и можете ли вы перегрузить этот метод в наследнике изменив тело метода?


немного отошедши от самого дела, попутно возник вопрос, а как IDE подсказывает вам какой тип перемееной может быть передан методу в качестве аргумета? неужто сама расскрывает if() ??

ifconfig
()

>как IDE подсказывает вам какой тип перемееной может быть передан методу в качестве аргумета
Не наезда ради, но токмо шутки ради: когда-то в тексте "почему настояшие программисты не пользуются паскалем" было написано "строгая типизация - для людей со слабой памятью" :-).

DonkeyHot ★★★★★
()

>Тоесть как наследник видит этот метод

Там по моему 3 способа - неперегруженый метод доступен по имени(self.method), перегруженый как ParentClassName.method(self,...) и для случаев сложного множественного наследования super(ClassName,self).method(...).

DonkeyHot ★★★★★
()

За шутку кнечно спасибо, но вудь вы сами заикнулись о больших проектах?
тут уж не то чтобы помнить, иногда ты можешь и не знать этого, ибо делает это другой человек, иногда ты его даже не знаешь %) Посему нормальная IDE, которая вам подскажит много чего полезного ( ну типа парметры метода или его написание) есть даже не роскошь, а просто необходимость. Или у вас тот же случай когда far forever!

насчет способа, спасибо за инфу, но я не совсем это хотел узнать..
попытаюсь еще раз

типа такого

class A
{
void test(param)
{
//тута ваши if, где рабираються типы параметров к примеру String и int
}
}

class B наследовать A
{
void test(param)
{
// тута метод, но в if разбираем тип параметра boolean
}
}

class C наследовать B
{
//а тута дергаем наш метод
test(param)
}


ну и какой код будет исполнен ? из класса А или B
если в описании метода не указан тип его аргуметов????

ifconfig
()
Ответ на: комментарий от ifconfig

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

anonymous
()

<Выбор для методов, делающих разные вещи (т.к. набор аргументов разный), одинаковых имен - имхо самая большая глупость,>
Зато, конечно,
add_int, add_long, add_long_long, add_float, add_double, add_long_double,
add_complex, add_real, add_rational, add_interval бла-бла-бла -- очень большая "умность".

AC
()
Ответ на: комментарий от AC

И часто это бывает нужно? Если часто - напишите класс generic_number.

anonymous
()
Ответ на: комментарий от ifconfig

<ну и какой код будет исполнен ? из класса А или B если в описании метода не указан тип его аргуметов???? >
А что, разве есть вопросы?

AC
()

я в Питоне пока новичок, но, ИМХО, действовать нужно не так вместо

from type import type class A: def blabla(x): if (type(x) is types.SomeClass1): делать то-то if (isinstanse(x,...)): делать другое

нужно class A: def blabla(x): делать что-то используя x.SomeMethod

соответственно если в классе, к которому принадлежит х, определен SomeMethod - все оки, иначе выдаст ошибку.

moron
()

Понял - попытка вторая
в:
class A:
def test(s,x):
if ...
else: raise TypeError
class B(A):
def test(s,x):
if ...
else: return A.test(s,x)
class C(B): ...
test(something)

вызывается B.test - независимо от типов параметров. Если B не определяет реакцию на переданый тип - вызовется A.test.

Насчет больших проектов - согласен. Тут правда есть такая вещь как docstring (как атрибут функции или класса) - вероятно IDE мог бы им пользоваться. Но я не пользуюсь python-specific IDE - посему не знаю.

DonkeyHot ★★★★★
()

>>Выбор для методов, делающих разные вещи (т.к. набор аргументов разный)
хорошо что это только твое imho.


>>вызывается B.test - независимо от типов параметров. Если B не определяет реакцию на переданый тип - вызовется A.test.

спасибо за разъяснения..
не все так плохо %) хотя лично мне не понятно, что выиграли разработчики питона, идя таким путем.. Или просто было охото выделиться %)
ибо по сути будет прога должана делать много лишних телодвижений, дергая несколко методов и определяя какой код нужно исполнить...

ifconfig
()

>не все так плохо
Кстати, если сравнить количество кода в C++ и python функциях, делающих разные действия с разными аргументами, то питоновский длиннее только на "def func()" - ибо количество "if(isistance)" будет равно количеству "void func(type x)".

Программа действительно делает лишние телодвижения. AFAIK С++ делает по другому - определяет функции test_int, test_float, test_classC - неявно и для программиста почти незаметно( пока из других языков их не придется вызывать). Как делает ява - я не знаю - может кто просветит.

Выиграли они( по сравнению с C++) в простоте подключения Сшных модулей - имя функции однозначно test а не test$#$@#$int@#$$#@ - и получили возможность обойтись без template-ов.

DonkeyHot ★★★★★
()
Ответ на: комментарий от ifconfig

>хорошо что это только твое imho.

Да, неплохо.
Ну так просветите зачем и для чего нужна перегрузка функций. Жалкие аргументы типа "для обхода граблей с зоопарком числовых типов (точнее одного типа в разных инкарнациях)" - принимаются с благодарностью и несокрушимым чувством собственной правоты.


anonymous
()
Ответ на: комментарий от anonymous

<Ну так просветите зачем и для чего нужна перегрузка функций. Ж>

Для полиморфизма, например. Когда я, к примеру, обхожу граф, мне наплевать, как он представлен -- мне нужен просто список соседних вершин, и мне все равно, каким образом он получается. Зачем мне десять раз переписывать код для десяти различных представлений данных? Жалкие контраргументы вроде возможности выращивания высоченного дерева классов и запихивания всего и вся в виртуальные функции не принимаются.

AC
()
Ответ на: комментарий от AC

Для чего вы обходите граф? Для собственного удовольствия? А если вы, что-то при этом делаете, то без предположений о типе - никуда.

>Для полиморфизма, например.

Слова хорошие, а фраза непонятная. Разверните, пожалуйста, с примером.

P.S. Да вы прямо мысли читаете. Но с чего вы взяли, что оно будет высоченным?

anonymous
()

<Для собственного удовольствия? А если вы, что-то при этом делаете, то без предположений о типе - никуда.>

Вы читать умеете? Тип элементов действительно нужен, а вот тип _самого_ графа -- нет. При "обходе" графа абсолютно все равно, как он представлен -- как матрица, как список вершин или как еще.

<Слова хорошие, а фраза непонятная. Разверните, пожалуйста, с примером. >

Да вроде выше объяснил и пример привел. Логически одна и та же операция (получение списка смежных вершин) "внутри" в зависимости от представления делает совершенно разные вещи (бегает по матрице или просто отдает список). Нет смысла называть одну и ту же операцию ("получение списка смежных вершин") по-разному -- ("получение списка смежных вершин представления в виде матрицы", "списка списков", "списка множеств", "множества множеств", etc).

<Но с чего вы взяли, что оно будет высоченным? >

Да так оно всегда и бывает. А виртуальные функции -- зло, они слишком дорого стоят. Впрочем, эти соображения уже не для питонщиков.

AC
()
Ответ на: комментарий от AC

> Тип элементов действительно нужен, а вот тип _самого_ графа -- нет.
> При "обходе" графа абсолютно все равно, как он представлен -- как
> матрица, как список вершин или как еще.

Как мне кажется "тип графа" - граф, а "матрица, список вершин" - детали реализации (невидимые разумеется). Может я чего-то (или много чего) не понимаю?

> Нет смысла называть одну и ту же операцию ("получение списка смежных
> вершин") по-разному

Разумеется. Операция одна - "получение списка смежных вершин". И ее результат один - "список смежных вершин". И реализуйте его как вздумается - все равно виден лишь открытый интерфейс.

> А виртуальные функции -- зло, они слишком дорого стоят.

Да вы шутник. И что же дешево? (Не для питонщиков ессно.)

> Вы читать умеете?

Нет.


anonymous
()

<Как мне кажется "тип графа" - граф, а "матрица, список вершин" - детали реализации (невидимые разумеется). Может я чего-то (или много чего) не понимаю?>

Совершенно верно. Поэтому и функция должна называться adjacent_vertices и перегружаться соответственно типам графа --
adjacent_vertices(const adjacency_list& G, ...);
adjacent_vertices(const adjacency_matrix& G,...);
etc.
Выстраивать иерархию возможных реализаций графа с соответствующим виртуальным методом adjacent_vertices -- дорого и некрасиво.

<Да вы шутник. И что же дешево?>

Полиморфизм времени компиляции, инлайнинг и оптимизация через "границы" методов соответственно.

AC
()

- Ну чем, чем?
- Чем грузины.

> Выстраивать иерархию возможных реализаций графа с соответствующим
> виртуальным методом adjacent_vertices -- дорого и некрасиво.

Зачем выстраивать иерархию _возможных_ реализаций графа. Надо лишь хорошо продумать его открытый интерфейс - то, что делает его именно графом. Когда нужна будет особая реализация (единственная разумная причина - повышение производительности каких-то операций) - тогда и родим нужного графа-мутанта. На потребителях это никак не скажется.

> Поэтому и функция должна называться adjacent_vertices

Какая-такая функция? Мы вроде говорим о том как граф обязан отвечать на сообщение "покажи-ка вершины, смежные с такой-то вершиной"?

> Полиморфизм времени компиляции, инлайнинг и оптимизация через
> "границы" методов соответственно.

Это реализуемо? Не "в принципе", а чтобы реальный машинный код был меньше и быстрее?



anonymous
()

2AC: а можно более подробно, для тупого меня, объяснить, где-же там нужны типы-то, в графах?

тип элемента графа, в общем случае вообще не интересен. Как, и тип любого параметра передаваемого в функцию. нам передают ОБЪЕКТ, и мы ожидаем что этот объект поддерживает некий ИНТЕФЕЙС.

питон, в первую очередь - ДИНАМИЧЕСКИЙ ЯЗЫК.

напирмер если я в

def some_output(value), ожидаю что value будет строковым, то мне всеравно какой мне туда обхект всунут. Главное чтоб он мог себя представить в виде строки.

чтоб любой объект был представим в виде строки так, как мне нужно, я ему пишу метод def __str__(self). И так далее, и тому подобное.

на счет "полиморфизм времени компиляции" - нет тут компиляции. В этом плюс! Если нужна компиляция compile-time type check, и прочее - не берите python в качестве инсрумента. Это от других дверей ключ.

bormotov ★★★☆
() автор топика

<Надо лишь хорошо продумать его открытый интерфейс - то, что делает его именно графом. Когда нужна будет особая реализация >

Ну да, совершенно справедливо. "Если это ходит как утка, и крякает как утка -- это утка". Это и есть абстракция данных и полиформизм.
Последнего есть два вида -- рантаймовый, который реализуют виртуальные методы (никто не говорит, что они не нужны _вообще_), и времени компиляции, которые реализуется именно перегрузкой (и шаблонами в плюсах).

<Мы вроде говорим о том как граф обязан отвечать на сообщение "покажи-ка вершины, смежные с такой-то вершиной"?>

Да?? Ну тогда таки да -- в "чистом" ООП без перегрузки действительно _можно_ обойтись. Но и там она _бывает_ нужной, чтобы избежать утомительного double dispatching.

<Это реализуемо? Не "в принципе", а чтобы реальный машинный код был меньше и быстрее? >

Да. Например, продвинутые компиляторы плюсов это хорошо умеют.

AC
()
Ответ на: комментарий от bormotov

<Если нужна компиляция compile-time type check, и прочее - не берите python в качестве инсрумента. Это от других дверей ключ. >

Да. Видимо, я просто не понял, что имел в виду анонимус, с которым мы дискутируем. Насколько я понял, он имел в виду, что перегрузка не нужна _вообще_. Если бы он написал, что перегрузка не нужна _в_питоне_, я бы с ним и спорить не стал -- зачем спорить с очевидным?

AC
()
Ответ на: комментарий от AC

2АС

Нет, я имел ввиду именно ненужность перегрузки "вообще".
Double dispatching - по-моему "единственно правильный путь".

> продвинутые компиляторы плюсов это хорошо умеют

Хотелось бы узнать, какие именно компиляторы настолько продвинуты?
Ведь без соответствующего компилятора "полиморфизм времени компиляции" - самолет Максима.

anonymous
()

<Double dispatching - по-моему "единственно правильный путь". >

Но это же _убийственно_ медленно...

<Хотелось бы узнать, какие именно компиляторы настолько продвинуты? >

Например, KAI, comeau вроде тоже. Скоро будет в ICC.

AC
()

> Например, KAI, comeau вроде тоже. Скоро будет в ICC.

Будет - посмотрим. Нельзя не согласится с идеей как можно больше загрузить компилятор. Но, к сожалению, большинство испробованных мной компиляторов вели себя "по Лему" (преодолевали предел разумности ;) ) и спихивали все в run-time.

> Но это же _убийственно_ медленно...

Все шутите ...

anonymous
()

<Все шутите ... >

Да уж какие тут шутки. То, что double dispatching -- красиво, но медленно, известно уже очень давно. Если таким образом вызывается "небольшой" метод (а в чистом ООП методы чаще всего небольшие), затраты на вызов сам по себе могут быть сравнимы с временем выполнения собственно кода. Даже если нынешние железки быстрые, это не повод грузить их бесполезной работой.

AC
()

2AC (*) (2002-10-20 00:01:50.243):

скажем так - в том виде, в котором перегрузка есть например в c++/java в питоне она не нужна. Тут просто с другой стороны подход. Я бы сказал со стороны SmallTalk'а (но утверждать не возьмусь, практического использования SmallTalk нету ;).

Если вдуматься, в компилируемых языках перегрузка операторов нужна только для тех типок, которые "простые". У которых нет методов. Это уже где-то тут звучало - подпорка, по сути ;)

anonymous
()

>>Нет, я имел ввиду именно ненужность перегрузки "вообще".
вот как..
ладно вдаваться в споры бесполезно.. Кстати, если не нужна то просто не используй.

ifconfig
()

2 ifconfig

> Кстати, если не нужна то просто не используй.

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

2 anonymous (*) (2002-10-20 11:46:51.405)

> Это уже где-то тут звучало - подпорка, по сути ;)

Согласен - костыли. Да и само существование таких "типов" в таком виде - ;).

anonymous
()
Ответ на: комментарий от LamerOk

Читая сообщения, я не вполне понял о чем здесь идет спор. Поэтому просто скажу, почему и ради чего я, например, использую Python.

1. Это простота и скорость разработки работающего прототипа, на котором можно полностью отладить всю логику программной системы. Скорость работы программ здесь не главное. А объектно-ориентированность это большой плюс, несмотря на то, что не все здесь доделано в языке. Но здесь на лицо прогресс. 2) С его помощью легко подключать и использовать практически любые библиотеки, языки и программы. Так что тут нет преград. Если, скажем, нужно какой-то кусок решить на Prolog'е -- можно воспользоваться им через wrapper. Python это хороший "клей" для объединения в одно целое. Если что-то требует скорости - то оно пишется на том языке, который позволяет добиться результата и подключается к прогрммам на Python. 3) Когда протитип на Python отлажен, то узкие места просто переписываются на C или C++. Сейчас уже есть средства, которые помогают ускорить этот процесс.

Как правило, это позволяет добиться приемлемой производительности для многих задач.

Ну и последнее (может быть главное), он мне просто нравится.

Если кому-то нравится другой язык -- программируйте на здоровье на нем. На то разнообразные языки программирования и существуют, чтобы можно было выбрать наиболее подходящий для решения задачи и удобный для разработчика.

szport
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.