В данной статье речь пойдет об объявлении и использовании функций внути других функций. Ничего не поняли? Не беда, читайте дальше, поймете!
Надеюсь вы умеете создавать и использовать функции. Если нет, то эта статья не для вас, учимся пользовться функциями и только тогда возвращаемся к этой статье.
Итак, функции, если вы еще незнали, можно объявлять не только в основном коде, но и в других функциях. Для наглядности рассмотрип следующий пример:
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
Глобальные переменные в функции не надо объявлять global, если не там она не будет изменяться. Для чтения и так можно юзать
0 ответить