LINUX.ORG.RU

Вложеные функции в python


0

0

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


а также интересует, применимость правила "функция должна вмещаться в одну страницу" к методу/функции с вложеными функциями

chicane
() автор топика

Для декораторов (если декоратор с аргументами, то до 3 вложенных может быть). Если необходимо замыкание.

Во всех остальных случаях лучше как метод, либо вообще вынести как отдельную функцию на уровень модуля.

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

> к методу/функции с вложеными функциями

Если у вас несколько вложенных функций, да еще они длиннее нескольких строк, то вы что-то делаете неправильно.

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

>Во всех остальных случаях лучше как метод, либо вообще вынести как отдельную функцию на уровень модуля.

ну вот к примеру есть некий gui. Пользователь нажимает определенную кнопку, для этой кнопки вызывается функция-callback, её вроде как и методом класса нельзя назвать, и вынести на уровень модуля тоже рука не поднимается... Вот куда её?

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

> методом класса нельзя назвать

Всю логику гуя можно объединить в класс и вешать его методы как колбеки (a la java-way).

> вынести на уровень модуля тоже рука не поднимается

Если первый способ не подходит, то на уровень модуля (a la python-way)

> Вот куда её?

В любом случае не вложенной функцией. Если конечно для вас юниттесты и повторное использование кода хоть что-то значат.

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

>Всю логику гуя можно объединить в класс

это и есть класс (widget в pygtk), но тем не менее назвать callback кнопки внутри этого виджета методом этого класса сложно...

>В любом случае не вложенной функцией. Если конечно для вас юниттесты и повторное использование кода хоть что-то значат.

как в данном случае можно повторно использовать эти функции, если они практически уникальные для разных групп кнопок?

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

> Пользователь нажимает определенную кнопку, для этой кнопки вызывается функция-callback, её вроде как и методом класса нельзя назвать

Почему же нельзя. Обработчики событий - это часть логики вашего gui-класса. В принципе можно и вложенными функциями, если у вас gui из 2-х кнопок. Но лучше так не делать, чтобы потом не переписывать, когда код разрастётся. Вложенные функции нужны для замыканий и декораторов, как тут уже сказали.

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

> widget в pygtk

У PyGTK приличные туториалы где не просто так показывают классы, методы и колбеки:

http://www.pygtk.org/pygtk2tutorial/ch-GettingStarted.html#sec-HelloWorld

Также рекомендую углубится в ООП (в design patterns в частности. И уж точно не городить вложенные функции там, где они не нужны.

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

> это и есть класс (widget в pygtk), но тем не менее назвать callback кнопки внутри этого виджета методом этого класса сложно...

Я бы порекомендовал создать отдельный модуль или класс, агрегирующий виджеты, и поместить обработчики событий и прочую gui-specific логику в этот класс.

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

>> Можно пример?

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

kto_tama ★★★★★
()

> Меня интересует область, где можно применять их?

Функции, которые не нужны за пределами объемлющей функции.

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

> Функции, которые не нужны за пределами объемлющей функции.

(любопытно) а в питоне можно (указатель на?) вложенную функцию сохранить в глобальной переменной, и потом вызвать? что тогда случиться?

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

> а в питоне можно (указатель на?) вложенную функцию

В питоне вообще всё - ссылки.

> сохранить в глобальной переменной, и потом вызвать?

def make_adder(a):
    def adder(b):
        return a + b
    return adder

add3 = make_adder(3)
print add3(5)  # выведет 8

Это называется замыкание и есть в любом высокоуровневом языке (даже в отдельных компиляторах с++ уже реализовали эту часть из грядущего стандарта)

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

>Это называется замыкание и есть в любом высокоуровневом языке (даже в отдельных компиляторах с++ уже реализовали эту часть из грядущего стандарта)

В c++0x есть только downward funarg. Т.е. время жизни внутренней функции ограничено временем жизни объемлющей. Для иного нужен сборщик мусора, которого, конечно же, нету.

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

> В c++0x есть только downward funarg. Т.е. время жизни внутренней функции ограничено временем жизни объемлющей. Для иного нужен сборщик мусора, которого, конечно же, нету.

Я тут постил уже (простенький правда) пример upward funarg на обычных плюсах, без 0Х. Сборщик мусора, естественно, не обязателен, можно использовать правильную семантику копирования, на крайняк счетчики ссылок.

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

> В c++0x есть только downward funarg. Т.е. время жизни внутренней функции ограничено временем жизни объемлющей. Для иного нужен сборщик мусора, которого, конечно же, нету.

Сборщики мусора нужны для технологии "делаем альтернативное ООП: юзаем стэковый фрейм вместо инстанса класса", которая не имеет известных мне преимуществ над обычным ООП. Еще для чего они нужны?

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

> Сборщики мусора нужны для технологии "делаем альтернативное ООП: юзаем стэковый фрейм вместо инстанса класса"

В Смоллтоке есть сборщик мусора. Не нужен?

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

> В Смоллтоке есть сборщик мусора. Не нужен?

Не нужен. region infernce наше все.

Впрочем, возможно и нужен... для программирования прототипов например.

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

>> В Смоллтоке есть сборщик мусора. Не нужен?

> Не нужен. region infernce наше все.

И это качественно отличается от сборки мусора?

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

> И это качественно отличается от сборки мусора?

Хотя бы тем, что есть настоящие указатели, и нет тормозов на сборку мусора. Хотя память имеет возможность несколько фрагментироваться, если этих регионов много (но не в труху, надеюсь).

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

>Не нужен. region infernce наше все

region infernece будет работать только в тривиальных случаях. реализуйка мне region inference для чего-то типа equinox ;)

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

> и нет тормозов на сборку мусора.

А тут ещё можно поспорить. Сборка мусора, в даже, например, работает в параллельном потоке с минимальной паузой всего остального.

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

> region infernece будет работать только в тривиальных случаях.

Прочти, сначала, что ли, прежде чем...

This paper describes a memory management discipline for programs that perform dynamic memory allocation and de-allocation. At runtime, all values are put into regions. The store consists of a stack of regions. All points of region allocation and deallocation are inferred automatically, using a type and effect based program analysis. The scheme does not assume the presence of a garbage collector.

http://www.irisa.fr/prive/talpin/papers/ic97.pdf

> реализуйка мне region inference для чего-то типа equinox ;)

На яве любят лепить кривое гавно. Впрочем, конкретно об equinox ничего пока не скажу.

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

>http://www.irisa.fr/prive/talpin/papers/ic97.pdf

Прочту. Но то, что гарбадж коллекшн больше распространён (среди компетентых людей, а не леммингов, так что аналог с виндой будет не уместен) как бэ всё-таки намекает.

>На яве любят лепить кривое гавно

На любом языке любят лепить кривое говно.

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

> Но то, что гарбадж коллекшн больше распространён (среди компетентых людей, а не леммингов, так что аналог с виндой будет не уместен) как бэ всё-таки намекает.

GC это как раз для леммингов. Это яву-то делали компетентные люди! ROFL!!! только в 2005 году сделать дженерики!

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

> для чего-то типа equinox

что-то я не могу найти хорошей статьи по архитектуре equinox -- всякие туториалы "как написать ant-файл для equinox" не в счет

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

> Это яву-то делали компетентные люди!

Рантайм явы делали таки очень компетентные люди. Проектирование языка - другой вопрос, там много политики.

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

> среди компетентых людей

хотя некоторые говорят, что C# вышел лучше явы из-за того, что были учтены ее ошибки, я считаю, что Hejlsberg поумнее -- например, properties былы еще в дельфи

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

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

> Рантайм явы делали таки очень компетентные люди.

Подробнее?

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

>Это яву-то делали компетентные люди!

Я не имею ввиду язык. А с языком там чисто политические проблемы.

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

>что-то я не могу найти хорошей статьи по архитектуре equinox

Я не совсем точно высказался - не только equenox, а вся плагинная система эклипса. Там не понять кто у гого парент. Из-за этого гарбадж коллекшн там очень естественнен.

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

>> Вот куда её?

>В любом случае не вложенной функцией

Обоснуй.

> Если конечно для вас юниттесты и повторное использование кода хоть что-то значат.

Юниттестируй и повторно используй объемлющую функцию. То, что делается вложенным, по определению специфично для объемлющей функции.

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

>В любом случае не вложенной функцией. Если конечно для вас юниттесты и повторное использование кода хоть что-то значат.

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

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

> Юниттестируй и повторно используй объемлющую функцию.

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

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

> Вложенная функция полный аналог прайват-метода

Это не python-way. В питоне нет настоящих приватных методов (даже при именовании __function) и это его идеология. Вложенные функции никогда для этого не предназначались и в python-сообществе их так никто не использует.

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

Вы можете привести пример (не считая декораторов, замыканий и фабрик) когда вложенная функция (или несколько) будет выгоднее функтора или простых функций?

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

>Это не python-way.

Гвидо, Вы? Извините, не узнал под толстым гримом ;)

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

Да пожалуйста - в алгоритме HeapSort в функции Heapify я-бы сделал Throw-Down внутренней функцией - снаружи она не нужна.

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

> Понимаю, когда объемлющая функция всего лишь фабрика, тогда ладно. А если наделать несколько внутренних функций, да ещё и немаленьких, как хочет автор топика,

Чувство меры и здравый смысл необходимы, как и всегда.

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

>> Вложенная функция полный аналог прайват-метода

> Это не python-way

"Не держись за устав, как слепой за стену" (c)

Кстати, к паттернам это тоже отностится.

> Вложенные функции никогда для этого не предназначались и в python-сообществе их так никто не использует.

Не говори за всех.

tailgunner ★★★★★
()

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

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

>> И это качественно отличается от сборки мусора?

>Хотя бы тем, что есть настоящие указатели, и нет тормозов на сборку мусора.

Любая более-менее сложная программа течет по определению, и руки тут не причем, поскольку весь реальный код написан через жопу. Собственно для работы в режиме 24/7 есть два выхода: либо запускать внешний код через popen либо использовать VM c GC типа жабы.

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

Сразу 2 ошибки:

1. Some games have been known to run with only a few KiB of system memory free. Some games run with no memory free at all and install an out-of-memory callback to free memory from elsewhere to satisfy the current request.

2. GC сам по себе не предотваращает утечку памяти, без soft/weak/phantom указателей память будет течь.

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