Keywords: easytut

Далее: Списки Наверх: Курс языка Python для начинающих Назад: Отладка программ Содержание
В этой главе

- Создание функций
- Переменные в функциях
- Детальное изучение функций
- Примеры
- Упражнения

# Определения функций

# Создание функций

Начиная эту главу, я представлю пример того, что вы можете делать, но не должны (по этой причине не стоит печатать следующий пример):

    a = 23
    b = -23

    if a < 0:
        a = -a

    if b < 0:
        b = -b

    if a == b:
        print "The absolute values of", a,"and",b,"are equal"
    else:
        print "The absolute values of a and b are different"

Результат работы:

    The absolute values of 23 and 23 are equal

Эта программа выглядит слегка повторяющейся. (Программисты ненавидят повторять вещи – для этого существуют компьютеры). К счастью, Python позволяет создавать функции, чтобы избежать повторений. Та же программа в переписанном виде:

    a = 23
    b = -23

    def my_abs(num):
        if num < 0:
            num = -num
        return num

    if my_abs(a) == my_abs(b):
        print "The absolute values of", a,"and",b,"are equal"
    else:
        print "The absolute values of a and b are different"

Результат:

    The absolute values of 23 and -23 are equal

Главная особенность этой программы – команда `def`. `def` (сокращение от английского слова «определять») начинает определение функции. После `def` следует имя функции `my_abs`. Далее следует `(`, затем аргумент `num` (`num` передается из программы в функцию всякий раз, когда программа вызывает функцию). Команды после `:` выполняются, когда эта функция используется. Команды функции продолжаются выполняться, пока не заканчиваются команды функции или встречается команда `return`. Команда `return` возвращает значение туда, откуда вызывалась функция.

Обратите внимание, что значения `a` и `b` не меняются. Функции также могут быть использованы для повтора действий, которые не возвращают значения. Примеры:

    def hello():
        print "Hello"

    def area(width,height):
        return width*height

    def print_welcome(name):
        print "Welcome",name

    hello()
    hello()

    print_welcome("Fred")
    w = 4
    h = 5
    print "width =",w,"height =",h,"area =",area(w,h)

Результат:

    Hello
    Hello
    Welcome Fred
    width = 4 height = 5 area = 20

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

# Переменные в функциях

Конечно же, когда вы избавляетесь от повторяющихся мест в программе, у вас часто встречаются переменные в таких местах. С ними в Python поступают специальным образом. До этого момента все переменные, которые мы видели, были глобальными. В функциях существует специальный тип переменных, называемый локальным. Они существуют только пока выполняется функция. Когда у локальной переменной такое же имя, как и у другой переменной, такой как глобальной, локальная переменная скрывает другую переменную. Звучит непонятно? Надеюсь, следующий пример (несколько искусственный) прояснит это.

    a_var = 10
    b_var = 15
    e_var = 25

    def a_func(a_var):
        print "in a_func a_var = ",a_var
        b_var = 100 + a_var
        d_var = 2*a_var
        print "in a_func b_var = ",b_var
        print "in a_func d_var = ",d_var
        print "in a_func e_var = ",e_var
        return b_var + 10

    c_var = a_func(b_var)

    print "a_var = ",a_var
    print "b_var = ",b_var
    print "c_var = ",c_var
    print "d_var = ",d_var

Результат работы программы:

    in a_func a_var =  15
    in a_func b_var =  115
    in a_func d_var =  30
    in a_func e_var =  25
    a_var =  10
    b_var =  15
    c_var =  125
    d_var =
    Traceback (innermost last):
      File "separate.py", line 20, in ?
        print "d_var = ",d_var
    NameError: d_var

В этом примере переменные `a_var`, `b_var` и `d_var` - локальные когда они используются в функции `a_func`. После команды `return b_var + 10` они больше не существуют. Переменная `a_var` - автоматически локальная переменная, поскольку это имя параметра. Переменные `b_var` и `d_var` - локальные поскольку они появляются в функции слева от знака равенства в командах `b_var = 100 + a_var` и `d_var = 2*a_var` .

В функции переменная `a_var` равна 15 так как функция вызывается командой `a_func(b_var)`. Поскольку в это время `b_var` равно 15, функция вызывается как `a_func(15)`. В резудьтате этого получаем `a_var` равно 15 когда эта переменная внутри функции `a_func`.

Как видите, когда выполнение функции завершается, локальные переменные `a_var` and `b_var`, которые скрывали глобальные переменные с такими же именами, перестают существовать. В это время команда `print "a_var = ",a_var` выводит `10`, а не `15`, так как локальной переменной, скрывающей глобальную, больше не существует.

Обратите внимание на `NameError`, который появляется в конце. Это происходит поскольку переменная `d_var` больше не существует, так как функция `a_func` закончилась выполняться. Все локальные переменные уничтожаются при выходе из функции. Если вы хотите получить какую-либо величину от функции, вам надо использовать команду `return переменная`.

Последняя вещь, на которую нужно обратить внимание - это то, что `e_var` не меняется в функции `a_func`, поскольку это не параметр и не появляется там слева от знака равенства. Когда к глобальной переменной обращаются из функции, имеется в виду глобальная переменная вне функции.

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

# Детальное изучение функций

В будущем из этой части будет сделана отдельная глава.

Сейчас мы будем изучать в деталях следующую программу:

    def mult(a,b):
        if b == 0:
            return 0
        rest = mult(a,b - 1)
        value = a + rest
        return value

    print "3*2 = ",mult(3,2)

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

Вопрос: Что программа делает в начале?

Ответ: Прежде всего определяется функция mult:

    def mult(a,b):
        if b == 0:
            return 0
        rest = mult(a,b - 1)
        value = a + rest
        return value

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

Вопрос: Что происходит далее?

Ответ: Выполняется следующая после функции команда `print "3*2 = ",mult(3,2)`

Вопрос: И что она делает?

Ответ: Она выводит `3*2 =` и число, возвращаемое командой `mult(3,2)`.

Вопрос: Какое число выдает команда `mult(3,2)`?

Ответ: Чтобы выяснить это, нужно детально изучить функцию `mult`.

Вопрос: Что происходит в функции?

Ответ: Переменная `a` получает значение 3 и переменная `b` получает значение 2.

Вопрос: А затем?

Ответ: Выполняется команда `if b == 0:`. Так как `b` равно 2, это условие ложно, поэтому команда `return 0` пропускается.

Вопрос: Что дальше?

Ответ: Выполняется команда `rest = mult(a,b - 1)`. Она присваивает локальной переменной `rest` величину `mult(a,b - 1)`. Здесь `a` равно 3 и `b` равно 2, так что вызов функции выглядит так: `mult(3,1)`.

Вопрос: Чему же равно `mult(3,1)` ?

Ответ: Нужно просчитать функцию `mult` с параметрами 3 и 1.

Вопрос: Что происходит далее?

Ответ: Локальные переменые при новом вызове функции имеют следующие значения: `a` равно 3 и `b` равно 1. Так как это локальные переменные, они не влияют на предыдущие значения `a` и `b`.

Вопрос: А дальше?

Ответ: Так как `b` равно 1, условие для команды if ложно, следующей выполняется команда `rest = mult(a,b - 1)`.

Вопрос: Что делает эта команда?

Ответ: Она присваивает значение `mult(3,0)` в переменную rest.

Вопрос: И чему равно это значение?

Ответ: Нужно вызвать функцию еще раз. Сейчас `a` равно 3 и `b` равно 0.

Вопрос: Что происходит далее?

Ответ: Выполняется первая команда функции `if b == 0:`. Переменная `b` равна 0 поэтому выполняется `return 0`

Вопрос: И что делает команда `return 0`?

Ответ: Она возвращает из функции 0.

Вопрос: И что?

Ответ: Сейчас мы знаем, что `mult(3,0)` равно 0. Мы знаем что делала команда `rest = mult(a,b - 1)`, так как мы вызвали функцию `mult` с параметрами 3 и 0. Мы завершили выполнение `mult(3,0)` и сейчас мы выполняем `mult(3,1)`. В переменную `rest` присваивается 0.

Вопрос: Какая команда выполняется следующей?

Ответ: Команда `value = a + rest` выполняется следующей. В этом вызове функции `a=3` и `rest=0`, так что `value=3`.

Вопрос: Что происходит дальше?

Ответ: Выполняется команда `return value`. Она возвращает из функции 3. Она также завершает функцию `mult(3,1)`. После выполнения `return` мы возвращаемся к `mult(3,2)`.

Вопрос: Где мы были в `mult(3,2)`?

Ответ: Переменные имели следующие значения: `a=3` и `b=2`. Мы остановились на команде `rest = mult(a,b - 1)` .

Вопрос: Что происходит сейчас?

Ответ: В переменную `rest` присваивается 3. Следующая команда `value = a + rest` заносит в `value` величину `3+3` или 6.

Вопрос: Что происходит далее?

Ответ: Выполняется следующая команда, функция выдает 6 и завершается. Мы возвращаемся к команде `print "3*2 = ",mult(3,2)` которая выводит 6.

Вопрос: Что же происходит в целом?

Ответ: Мы использовали два факта при вычислении произведения двух чисел. Первый - любое число при умножении на 0 дает 0 (`x * 0 = 0`). Второй - одно число, умноженное на другое, равно первое число плюс первое число, умноженное на величину, на единицу меньше второго числа (`x * y = x + x * (y - 1)`). Получается, что `3*2` сначала преобразуется в `3 + 3*1`. Затем `3*1` преобразуется в `3 + 3*0`. Мы знаем, что любое число при умножении на 0 дает 0, поэтому `3*0` равно 0. Теперь мы можем высчитать `3 + 3*0`, то есть `3 + 0`, что равно `3`. Теперь мы знаем чему равно `3*1` и можем вычислить `3 + 3*1`, то есть `3 + 3`, что равно `6`.

Вот так это выглядит в целом:

    3*2
    3 + 3*1
    3 + 3 + 3*0
    3 + 3 + 0
    3 + 3
    6

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

# Примеры

factorial.py

    #определяем функцию вычисления факториала

    def factorial(n):
        if n <= 1:
            return 1
        return n*factorial(n-1)

    print "2! = ",factorial(2)
    print "3! = ",factorial(3)
    print "4! = ",factorial(4)
    print "5! = ",factorial(5)

Результат:

    2! =  2
    3! =  6
    4! =  24
    5! =  120

temperature2.py

    #перевод из градусов Фаренгейта в градусы Цельсия

    def print_options():
        print "Options:"
        print " 'p' print options"
        print " 'c' convert from celsius"
        print " 'f' convert from fahrenheit"
        print " 'q' quit the program"

    def celsius_to_fahrenheit(c_temp):
        return 9.0/5.0*c_temp+32

    def fahrenheit_to_celsius(f_temp):
        return (f_temp - 32.0)*5.0/9.0

    choice = "p"
    while choice != "q":
        if choice == "c":
            temp = input("Celsius temperature:")
            print "Fahrenheit:",celsius_to_fahrenheit(temp)
        elif choice == "f":
            temp = input("Fahrenheit temperature:")
            print "Celsius:",fahrenheit_to_celsius(temp)
        elif choice != "q":
            print_options()
        choice = raw_input("option:")

Пример работы:

    > python temperature2.py
    Options:
     'p' print options
     'c' convert from celsius
     'f' convert from fahrenheit
     'q' quit the program
    option:c
    Celsius temperature:30
    Fahrenheit: 86.0
    option:f
    Fahrenheit temperature:60
    Celsius: 15.5555555556
    option:q

area2.py

    #Написана Амосом Саттерли
    print
    def hello():
        print 'Hello!'

    def area(width,height):
        return width*height

    def print_welcome(name):
        print 'Welcome,',name

    name = raw_input('Your Name: ')
    hello(),
    print_welcome(name)
    print
    print 'To find the area of a rectangle,'
    print 'Enter the width and height below.'
    print
    w = input('Width:  ')
    while w <= 0:
        print 'Must be a positive number'
        w = input('Width:  ')
    h = input('Height: ')
    while h <= 0:
        print 'Must be a positive number'
        h = input('Height: ')
    print 'Width =',w,' Height =',h,' so Area =',area(w,h)

Пример работы:

    Your Name: Josh
    Hello!
    Welcome, Josh

    To find the area of a rectangle,
    Enter the width and height below.

    Width:  -4
    Must be a positive number
    Width:  4
    Height: 3
    Width = 4  Height = 3  so Area = 12

# Упражнения

Перепишите программу area.py главы 3.2 с отдельными функциями для вычисления площади квадрата, прямоугольника и круга (3.14 * радиус**2). Программа должна предоставлять пользователю возможность выбора.

Далее: Списки Наверх: Курс языка Python для начинающих Назад: Отладка программ Содержание