Опубликован: 22.12.2005 | Доступ: свободный | Студентов: 16501 / 504 | Оценка: 4.18 / 3.71 | Длительность: 16:16:00
ISBN: 978-5-9556-0109-0
Лекция 3:

Элементы функционального программирования

Функция: определение и вызов

Как уже говорилось, определить функцию в Python можно двумя способами: с помощью оператора def и lambda-выражения. Первый способ позволяет использовать операторы. При втором - определение функции может быть только выражением.

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

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

Определение функции должно содержать список формальных параметров и тело определения функции. В случае с оператором def функции также задается некоторое имя. Формальные параметры являются локальными именами внутри тела определения функции, а при вызове функции они оказываются связанными с объектами, переданными как фактические параметры. Значения по умолчанию вычисляются в момент выполнения оператора def, и потому в них можно использовать видимые на момент определения имена.

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

Функция одного аргумента:

def swapcase(s):
    return s.swapcase()

print swapcase("ABC")

Функция двух аргументов, один из которых необязателен и имеет значение по умолчанию:

def inc(n, delta=1):
    return n+delta

print inc(12)
print inc(12, 2)

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

def wrap(text, width=70, **kwargs):
   from textwrap import TextWrapper
   # kwargs  - словарь с именами и значениями аргументов
   w = TextWrapper(width=width, **kwargs)
   return w.wrap(text)

print wrap("my long text ...", width=4)

Функция произвольного числа аргументов:

def max_min(*args):
  # args - список аргументов в порядке их указания при вызове
  return max(args), min(args)

print max_min(1, 2, -1, 5, 3)

Функция с обычными (позиционными) и именованными аргументами:

def swiss_knife(arg1, *args, **kwargs):
  print arg1
  print args
  print kwargs
  return None

print swiss_knife(1)
print swiss_knife(1, 2, 3, 4, 5)
print swiss_knife(1, 2, 3, a='abc', b='sdf')
# print swiss_knife(1, a='abc', 3, 4)  # !!! ошибка

lst = [2, 3, 4, 5]
dct = {'a': 'abc', 'b': 'sdf'}
print swiss_knife(1, *lst, **dct)

Пример определения функции с помощью lambda -выражения дан ниже:

func = lambda x, y: x + y

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

В языке Python функция может возвратить только одно значение, которое может быть кортежем. В следующем примере видно, как стандартная функция divmod() возвращает частное и остаток от деления двух чисел:

def bin(n):
    """Цифры двоичного представления натурального числа """
    digits = []
    while n > 0:
        n, d = divmod(n, 2)
        digits = [d] + digits
    return digits

print bin(69)

Примечание:

Важно понять, что за именем функции стоит объект. Этот объект можно связать с другим именем:

def add(x, y):
  return x + y
addition = add  # теперь addition и add - разные имена одного и того же объекта

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

def mylist(val, lst=[]):
  lst.append(val)
  return lst

print mylist(1),
print mylist(2)

Вместо ожидаемого [1] [2] получается [1] [1, 2], так как добавляются элементы к "значению по умолчанию".

Правильный вариант решения будет, например, таким:

def mylist(val, lst=None):
  lst = lst or []
  lst.append(val)
  return lst

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

Андрей Егоров
Андрей Егоров

def bin(n):

"""Цифры двоичного представления натурального числа """

if n == 0:

   return []

n, d = divmod(n, 2)

return bin(n) + [d]

print bin(69)

Что значит здесь return[] ? Возвращает список? Непонятно какой список? Откуда он? 

 

 

Асмик Гаряка
Асмик Гаряка

Почему при вычислении рейтинга не учитывается уровень, как описано? Для всех курсов У=1, хотя для Специалист должно быть 2.

Лариса Матросова
Лариса Матросова
Россия
Аделина Федорова
Аделина Федорова
Россия, 155900