категории | RSS

В данной статье речь пойдет об объявлении и использовании функций внути других функций. Ничего не поняли? Не беда, читайте дальше, поймете!

Надеюсь вы умеете создавать и использовать функции. Если нет, то эта статья не для вас, учимся пользовться функциями и только тогда возвращаемся к этой статье.

Итак, функции, если вы еще незнали, можно объявлять не только в основном коде, но и в других функциях. Для наглядности рассмотрип следующий пример:

import appuifw
def summa():
def a():
a=appuifw.query(u'Vvedite a','number')
return a
def b():
b=appuifw.query(u'Vvedite a','number')
return b
print a()+b()

summa()


Разберем код:
Мы создаем функцию summa() которая должна будет считать сумму любых двух чисел. Далее мы создали еще две функции: a() и b(). Заметте, эти две функции созданны внутри функции summa(). В этих функциях выводяться окошки, в которых пользователю предлагаеться ввести числа для вычисления суммы и возвращаеться число введеное пользователем. Далее идет строка где вычисляеться сумма этих двух чисел, и выводиться на экран командой print. Эта строка принадлежит уже функции summa().

Перед переходом к рассмотрению более сложных примеров использования вложенных функций, рассмотрим некоторые особенности данного подхода.
Вложенные функции могут использоваться только внутри тех функции, в которых они были созданы. Рассмотрим предыдущий пример: мы создали функцию summa(), а в ней еще две функции a() и b() (на случай если вы забыли). Внутри функции summa(), мы можем спокойно исспользовать эти две функции. Но, вне summa(), мы не можем их использовать.

def summa():
def a():
a=appuifw.query(u'Vvedite a','number')
return a
def b():
b=appuifw.query(u'Vvedite a','number')
return b
print a()+b()

summa()


Скажем я ввел число a=4, а число b=1, на экран выведиться сумма этих чисел - 5. Теперь попробуем воспользоваться функцией a() вне функции summa().

a()


В результате произойдет ошибка:

Traceback (most recent call last):
File "E:\eff20111\inspect.py", line 213, in inspect
File "d:\iPro7_Inspecting\default.py", line 10, in ?
a()
NameError: name 'a' is not defined

Что значит функции с именем 'a' не обнаруженно.

Теперь о переменных
Любые переменные объявленные в основной функции, в том числе и глобальные, могут быть использованы во вложенной функции:

import appuifw
x='Hello'
def hello():
global x
name=appuifw.query(u'Your name','text')
def prt():
print x,name
prt()

hello()


В тоже время переменные объявленные во вложенной функции, не могут быть использованы в основной:

def a():
def b():
name='Python'
print name

a()


Результат:

Traceback (most recent call last):
File "E:\eff20111\inspect.py", line 213, in inspect
File "d:\iPro7_Inspecting\default.py", line 6, in ?
a()
File "d:\iPro7_Inspecting\default.py", line 4, in a
print name
NameError: global name 'name' is not defined

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

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

import appuifw,e32#импорт необходимых модулей

#далее идут функцию для элементов меню
#пример Canvas
def canvas():
appuifw.app.body=kan=appuifw.Canvas()
kan.text((10,30),u'Primer Canvas',0xff0000,'title')
appuifw.app.exit_key_handler=menu

#пример text
def text():
appuifw.app.body=txt=appuifw.Text()
txt.add(u'Primer text')
appuifw.app.exit_key_handler=menu

#функция выхода
def exit():
import os
os.abort()

#собственно само меню
def menu():
#функция которая будет выполняться при выборе элемента listbox
def select():
id=lsbx.current()
if id==0:
canvas()
elif id==1:
text()
else:
exit()

#список элементов меню
list=[u'Canvas',u'Text',u'Exit']
#сам listbox
appuifw.app.body=lsbx=appuifw.Listbox(list,select)

menu()
e32.Ao_lock().wait()#чтобы увидеть результат в консоли


Рассмотрим преимущества данной реализации:
- при выборе элемента listbox выполняеться необходимая функция;
- из функции можно вернуться назад, в наше меню на listbox;

Чтобы вы лучше поняли преимуществ данной реализации, рассмотрим еще несколько и их недостатки..

Создать просто listbox, в не функции, и функцию которая будет вызываться при выборе элемента меню:

def select():
id=lsbx.current()
if id==0:
canvas()
elif id==1:
text()
else:
exit()

list=[u'Canvas',u'Text',u'Exit']
appuifw.app.body=lsbx=appuifw.Listbox(list,select)


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

Теперь попробуем занести listbox, в функцию:

def select():
id=lsbx.current()
if id==0:
canvas()
elif id==1:
text()
else:
exit()

def menu():
list=[u'Canvas',u'Text',u'Exit']
appuifw.app.body=lsbx=appuifw.Listbox(list,select)

menu()


Таким образом мы сможем вернуться из некой функции в наше меню, но при условии что вы ее запустите. В данной реализации список выведиться на экран, но при выборе элемента произойдет ошибка, что-то типа переменная lsbx не найдена. Если вы внимательно читали о работе функций в Python, то должны знать, что после завершения функции, все переменные, если они не являються глобальными, удаляються (стираються, исчезают). Так вот, при выборе элемента меню функция menu() завершаеться и в месте с ней исчезают и все переменные использованные в ней. Начинаеться выполнение функции select(), но переменной lstb в этой функции, или где либо еще, нет, и поэтому происходит ошибка.

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

Напоследок хотелось бы пожелать удачи в изучении Python, и программировании на нем.
С ув. Сергей Сахно aka Punk_Joker

Punk_Joker
2011-07-01T06:43:31Z

Здесь находятся
всего 0. За сутки здесь было 0 человек

Комментарии 13

#3   Glo1bys    

Видно статью и куски кода, но что это, вообще не понятно


0 ответить

#3   Punk_Joker    

Ahad,
Статья. Или куски кода не видно?
-------------
Добавлено в 00.38: Обновление от 01/07/2011 00:38:26
============
Причина редактирования: неправильно написал ббкоды


0 ответить

#3   Ahad    

Прошу прощенья, но что это?
Вопрос риторический


0 ответить

Яндекс.Метрика