Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Создание функций пользователя

Поиск

ЛАБОРАТОРНАЯ РАБОТА №5

Тема: Разработка функций и модулей пользователя

Цель: Рассмотрение особенностей разработки функций и модулей пользователя

ОГЛАВЛЕНИЕ

1 Создание функций пользователя
1.1 Описание функции
1.1.1 Использование позиционных аргументов
1.1.2 Использование именованных аргументов
1.1.3 Использование аргументов, заданных по умолчанию
1.1.4 Использование аргументов, заданных списком
1.1.5 Использование аргументов, заданных словарем
1.2 lambda функции
1.3 Замыкание
1.4 Использование функции при сортировке
1.5 Использование функций при фильтрации и формировании данных
1.5.1 Использование функции filter()
1.5.2 Использование функции map()
1.5.3 Использование оператора yield
2 Создание модулей пользователя
3 Компиляция и выполнение фрагментов кода
3.1 Функция compile()
3.2 Функция exec()
3.3 Функция eval()
Индивидуальные задания

 

 

Создание функций пользователя

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

 

Описание функции

Описание любой функции начинается со служебного слова def и имеет следующий вид

def <имя функции>([<параметры>]):
<блок>.

Функция может не иметь формальных параметров, иметь один такой параметр или несколько. Если функция имеет несколько параметров, то они перечисляются через запятую.
Первой строкой блока функции может быть строка ее документирования (docstring), которая берется в тройные кавычки и в среде IDLE появляется на экране в качестве подсказки при вызове функции во время задания аргументов (см. также использование строки документирования при объявлении классов в подразделе 1.1 лаб. раб. №11).
Для возвращения значения функции используется оператор return. Если возвращается несколько значений, то они должны быть указаны в виде списка (см. раздел 2 лаб. раб. №3). Если оператор return не задан в блоке функции или указан без операнда, возвращается значение None (см. встроенные типы в разделе 4 лаб. раб. №1).
Функцию можно определять в модуле, внутри другой функции (см. подраздел 1.3) или в классе (см. подраздел 1.1 лаб. раб. №11). Функция, определенная в классе, называется методом.
Функции в языке Python являются объектами. С ними можно работать как и с другими объектами языка. В этом состоит их отличие от функций в таких языках, как Java, C++ и C#.
При вызове фукнции указыается ее имя и в скобках – аргументы (если функция их имеет). Число аргументов и их типы должны соответствовать числу и типам параметров функции. При выполнении функции значения аргументов присваиваются соответствующим параметрам.
В качестве примера создания функции, рассмотрим задачу генерации чисел Фибоначчи, уже приведенную в подразделе 6.3 лаб. раб. №1. Но теперь решение этой задачи реализуем в виде функции fibo(k), которая определяет первые k чисел Фибоначчи и возвращает их в виде списка:

>>> def fibo (k):
'''Формирование чисел Фибоначчи (k – их количество)'''
a,b,i,f=0,1,0,[]
while i<k:
f+=[b]
a,b=b,a+b
i+=1
return f

Отметим, что созданная функция является объектом:

>>> print (isinstance (fibo, object))
True,

который можно вызвать по имени, потому что встроенная функция callable() (см. раздел 8.1 лаб. раб. №1) возвращают значение True:

>>> print (callable (fibo))
True,

и получить 10 чисел Фибоначчи:

>>> print (fibo(10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Функция fibo() оформлена в виде файла ... \LAB6\fibo.py, имеет один параметр k, с помощью которого пользователь задает число необходимых ему чисел Фибоначчи. В строке документирования указано назначение функции и ее параметра.
Имеется несколько способов передачи значений параметрам функции:

· с помощью позиционных аргументов (см. подраздел 1.1.1);

· с помощью именнованных аргументов (см. подраздел 1.1.2);

· с помощью аргументов, имеющих значения по умолчанию (см. подраздел 1.1.3);

· с помощью аргументов, заданных списком (см. подраздел 1.1.4);

· с помощью аргументов, заданных словарем (см. подраздел 1.1.5).

 

Lambda функции

lambda функции широко используются в языках функционального программирования. Поэтому в языке Python осуществлена их поддержка:

>>> def f1 (n): return lambda x:x**n

>>> f2=f1(3)
>>> f2(5)
125

Можно просто вызвать функцию f1:

>>> f1(3)(5)
125

Использование lambda функции показано также в подразделе 1.5.2.

 

Замыкание

Замыкание – это особый вид функции, которая определена в теле другой функции и создается каждый раз при выполнении внешней функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции.
Ссылки на переменные внешней функции в случае замыкания действительны внутри вложенной функции даже если внешняя функция завершила работу и переменные вышли из области видимости. В объекте – функции привязаны к данным, в замыкании – данные привязаны к функции.
Приведем пример простого замыкания:

>>> def make_add (x):
def add (y):
return x+y
return add

>>> make_add(2)(3)
5

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

>>> def create_counter (count_calls=0):
def change_counter ():
count_calls+=1
return count_calls
return change_counter

возникает ошибка:

nboundLocalError: local variable 'count_calls' referenced before assignment.

Исправить положение можно, задав число вызовов в виде элемента списка:

>>> def create_counter (count_calls=[0]):
def change_counter ():
count_calls[0]+=1
return count_calls[0]
return change_counter

>>> create_counter()()
1
>>> create_counter()()
2
>>> create_counter()()
3.

 

Использование функции map()

Для формирования данных может быть использована встроенная функция map(function,iterable) (см. подраздел 8.1 лаб. раб. №1), которая имеет те же аргументы, что и функция map(), но выполняет не фильтрацию, а формирование с помощью функции function элементов итератора из элементов iterable.
В качестве примера рассмотрим формирование чисел вида x*x-1, заданного lambda функцией (см. подраздел 1.2), в диапазоне от 1 до 10, представленных в виде кортежа:

>>> tuple (map (lambda x:x*x-1, range (1,10)))
(0, 3, 8, 15, 24, 35, 48, 63, 80)

 

Функция compile()

Встроенная функция compile(source, filename, mode, flags=0,dont_inherit=False, optimize=-1) – компилирует исходный код, указанный аргументом source, в код или объект AST (см. подраздел 8.1 лаб. раб. №1). Объекты кода могут быть выполнены с помощью функций exec() (см. подраздел 4.2) или eval() (см. подраздел 4.3).
Исходный код source может быть строкой (см. раздел 2 лаб. раб. №2), типом bytes (см. подраздел 3.1 лаб. раб. №4) или AST объектом (для получения информации о том, как работать с AST объектами необходимо обратиться к документации модуля ast).
Аргумент filename должен указывать имя файла, откуда будет прочитан искодный код (если код находится в интерактивной среде разработки – указывается значение '<string>').
Аргумент mode указывает вид кода, который должен быть компилирован. Это может быть 'exec', если код состоит из последовательности операторов (используется в большинстве случаев), 'eval' – если код состоит из единственного выражения (если указать оператор, то возникнет исключение "invalid syntax"), или 'single', если код состоит из единственного оператора, используемого в интерактивном режиме (если операторов больше – они не будут выполняться).
Необязательные аргументы flags и dont_inherit определяют, какие операторы future_statement (см. PEP 236 http://legacy.python.org/dev/peps/pep-0236/) влияют на компилящию исходного кода.
Необязательный аргумент optimize указывает уровень оптимизации компилятора. Значение, принимаемое по умолчанию (-1), выбирает уровень оптимизации интерпретатора, заданный опцией -O. Явно задавать можно следующие уровни:

· 0 – нет оптимизации, значение __debug__ равно True;

· 1 – функции assert() удалены, значение __debug__ равно False;

· 2 – строки документации удалены также.

Функция compile() вызывает исключение SyntaxError, если компилируемый код неверен, и исключение TypeError, если исходный код содержит байты null.
Отметим, когда компилируется строка, заданная на нескольких рядках, в режимах 'single' или 'eval', ввод может быть завершен даже одним символом перевода на новую строку (\n).
Изменения в версии 3.2: разрешается использование символов перевода на новую строку в стиле Windows и Mac. Также ввод в режиме 'exec' больше не должен заканчиваться по символу перевода на новую строку. Добавлен параметр оптимизации.
Приведем пример компиляции небольшого фрагмента кода:

>>> my_code= compile ('''
x=5
y=x**3+1
print(y) ''', '<string>', 'exec')

Переменная my_code указывает на скомпилированный фрагмент кода. Определим ее тип:

>>> type (my_code)
<class 'code'>

Таким образом скомпилированный код имеет тип (класс) code.

 

Функция exec()

Встроенная функция exec(object[, globals[, locals]]) поддерживает динамическое выполнение кода языка Python (см. подраздел 8.1 лаб. раб. №1). Аргумент object должен быть строкой или объектом типа code. Если это строка, то производится ее грамматический разбор, как это делается с операторами языка. После чего происходит ее выполнение (до завершения или до появления ошибки). Если это объект типа code, то он просто выполняется. Надо быть готовым к тому, что операторы return и yield могут не выполняться вне определения функции даже внутри контекста кода, передаваемого функции exec(). Возвращается значение None.
Во всех случаях, когда необязательная часть аргументов опущена, код выполняется в текущем пространстве имен. Если указан только аргумент globals, должен быть словарь, который будет использоваться как для глобальных, так и для локальных переменных. Если указаны аргуметры globals и locals, они будут использованы соответственно для глобальных и локальных переменных. Если указан аргумент locals, он может быть типа отображения. Необходимо помнить, что на уровне модуля globals и locals являются одним и тем же словарем. Если функция exec() получает два отдельных объекта – globals и locals, код будет выполняться как будто они были объявлены в определении класса.
Если словарь globals не содержит значение для ключа __builtins__, ссылка на словарь встроенного модуля builtins будет вставлена под этим ключем. Это можно контролировать, поскольку builtins доступен выполняемому коду путем всключения собственного словаря __builtins__ в пространство имен globals перед передачей кода функции exec().
Отметим, во-первых, что встроенные функции globals() и locals() (см. подраздел 2.4) возвращают соответственно глобальный и локальный словари, которые могут использоваться как второй и третий аргументы функции exec().
Во-вторых, значения по умолчанию аргумента locals() берутся так, как приведено в фукнции locals(): модификации значений по умолчанию словаря locals() не допускаются. Необходимо явно передать словарь locals(), если нужно увидеть влияние кода на locals() после того, как функция exec() вернет значение.
Приведем два примера использования фукнции exec(): один с аргументом в виде строки:

>>> x=1.25
>>> exec ('y=x*x+x+1')
>>> y
3.8125

другой – с аргументом в виде скомпилированного кода. Для этого воспользуемся переменной my_code, полученной в подразделе 4.1:

>>> exec (my_code)
126

 

Функция eval()

Аргументами встроенной функции eval (expression, globals = None, locals = None) (см. подраздел 8.1 лаб. работы №1) являются: строка expression, задающая выражение, и необязательные словари globals и locals, указывающие пространства имен соответственно глобальных и локальных переменных (см. подраздел 2.4). При выполнении функции осуществляется грамматический разбор выражения и вычисление его значения:

>>> x=5
>>> eval ('x+1',{ 'x':1})
2

Если аргумент locals опущен, значения берутся из словаря globals. Если опущены оба необязательных аргумента, выражение вычисляется в том окружении, в котором функция eval() была вызвана:

>>> x=5
>>> eval ('x+1')
6.

В подразделе 1.1.3 была рассмотрена функция val(x, y, op), выполняющая заданные арифметические операции (op) над двумя числами (x и y). Использование функции eval() в блоке функции val() (новый вариант функции – new_val()) не только делает описание функции намного компактнее:

>>> def new_val (x, y, op):
return eval (str (x)+op+ str (y)),

но и существенно расширяет функциональные возможности функции eval(), поскольку функция new_val() может выполнять не только те операции, которые были предусмотрены для функции val():

>>> new_val(3, 2, '/')
1.5,

но и любые двуместные операции для операндов x и y:

>>> new_val(3,2,'**')
9.

Причем даже такие, которых нет среди стандартных операций языка Python:

>>> new_val(3, 2, '**2+')
11.

В заключение отметим, что eval(repr(object)) возвращает object. Например:

>>> eval (repr ("cat"))
'cat'.

 

Индивидуальные задания

Разработать программу на языке Python, в которой:

· 1 Определена и выполнена функция func1() с аргументами в виде списка чисел (целых и с плавающей точкой), которая выполняет операцию, заданную колонкой "Операция" табл. №1):

§ 1 – определение суммы квадратов элементов списка;

§ 2 – определение максимального числа среди элементов списка;

§ 3 – определение квадратных корней элементов списка;

§ 4 – определение минимального числа среди элементов списка;

§ 5 – определение среднего значения элементов списка;

§ 6 – определение разности между суммой четных чисел и суммой нечетных чисел (если число не целое – привести к целому);

§ 7 – определение разности между суммой кубов и суммой квадратов элементов списка.

· 2.1 Создан словарь a_dict (числом элементов не меньше 8), ключи которого именуются произвольно, а значения заданы в виде, указанном колонкой "Вид значений" табл. №1):

§ 1 – латинские буквы;

§ 2 – цифры;

§ 3 – буквы кириллицы;

§ 4 – наименования встроенных функций;

§ 5 – наименования операторов.

При этом отдельные ключи (числом не меньше трех) должны иметь одинаковое значение.

· 2.2 Определена функция func2(), которая имеет два аргумента, первый – в виде словаря, второй – указывает значение ключа словаря. Функция func2() возвращает список ключей словаря, значения которых совпадают со значениями второго аргумента.

· 3.1 Создан список a_list, элементы которого имеют тип, указанный колонкой "Тип" табл. №1):

§ 1 – числа;

§ 2 – логические значения;

§ 3 – строки;

§ 4 – списки с элементами в виде чисел;

§ 5 – списки с элементами в виде строк.

· 3.2 Определена функция func3(), которая преобразует каждый элемент заданного списка a_list в целое число (механизм преобразования – на усмотрение студента).

· 3.3 Выполнена с использованием функции func3() и метода sort() сортировка элементов списка a_list:

§ для четных номеров индивидуального задания – по возрастанию;

§ для нечетных номеров индивидуального задания – по убыванию.

· 4.1 Задана строка str_code, содержащая небольшой фрагмент кода на языке Python и получен скомпилированный с помощью встроенной функции compile() код – comp_code.

· 4.2 С помощью встроенной функции exec() код comp_code исполнен.

Таблица 1 – Перечень индивидуальных заданий

Номер п/п Операция Вид значений Тип
1 1 5 1,5
2 2 4 2,3
3 3 3 2,4
4 4 2 2,5
5 5 1 3,4
6 6 5 3,5
7 7 4 1,5
8 1 3 2,3
9 2 2 2,4
10 3 1 2,5
11 4 5 3,4
12 5 4 3,5
13 6 3 1,5
14 7 2 2,3
15 1 1 2,4
16 2 5 2,5
17 3 4 3,4
18 4 3 3,5

 

ЛАБОРАТОРНАЯ РАБОТА №5

Тема: Разработка функций и модулей пользователя

Цель: Рассмотрение особенностей разработки функций и модулей пользователя

ОГЛАВЛЕНИЕ

1 Создание функций пользователя
1.1 Описание функции
1.1.1 Использование позиционных аргументов
1.1.2 Использование именованных аргументов
1.1.3 Использование аргументов, заданных по умолчанию
1.1.4 Использование аргументов, заданных списком
1.1.5 Использование аргументов, заданных словарем
1.2 lambda функции
1.3 Замыкание
1.4 Использование функции при сортировке
1.5 Использование функций при фильтрации и формировании данных
1.5.1 Использование функции filter()
1.5.2 Использование функции map()
1.5.3 Использование оператора yield
2 Создание модулей пользователя
3 Компиляция и выполнение фрагментов кода
3.1 Функция compile()
3.2 Функция exec()
3.3 Функция eval()
Индивидуальные задания

 

 

Создание функций пользователя

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

 

Описание функции

Описание любой функции начинается со служебного слова def и имеет следующий вид

def <имя функции>([<параметры>]):
<блок>.

Функция может не иметь формальных параметров, иметь один такой параметр или несколько. Если функция имеет несколько параметров, то они перечисляются через запятую.
Первой строкой блока функции может быть строка ее документирования (docstring), которая берется в тройные кавычки и в среде IDLE появляется на экране в качестве подсказки при вызове функции во время задания аргументов (см. также использование строки документирования при объявлении классов в подразделе 1.1 лаб. раб. №11).
Для возвращения значения функции используется оператор return. Если возвращается несколько значений, то они должны быть указаны в виде списка (см. раздел 2 лаб. раб. №3). Если оператор return не задан в блоке функции или указан без операнда, возвращается значение None (см. встроенные типы в разделе 4 лаб. раб. №1).
Функцию можно определять в модуле, внутри другой функции (см. подраздел 1.3) или в классе (см. подраздел 1.1 лаб. раб. №11). Функция, определенная в классе, называется методом.
Функции в языке Python являются объектами. С ними можно работать как и с другими объектами языка. В этом состоит их отличие от функций в таких языках, как Java, C++ и C#.
При вызове фукнции указыается ее имя и в скобках – аргументы (если функция их имеет). Число аргументов и их типы должны соответствовать числу и типам параметров функции. При выполнении функции значения аргументов присваиваются соответствующим параметрам.
В качестве примера создания функции, рассмотрим задачу генерации чисел Фибоначчи, уже приведенную в подразделе 6.3 лаб. раб. №1. Но теперь решение этой задачи реализуем в виде функции fibo(k), которая определяет первые k чисел Фибоначчи и возвращает их в виде списка:

>>> def fibo (k):
'''Формирование чисел Фибоначчи (k – их количество)'''
a,b,i,f=0,1,0,[]
while i<k:
f+=[b]
a,b=b,a+b
i+=1
return f

Отметим, что созданная функция является объектом:

>>> print (isinstance (fibo, object))
True,

который можно вызвать по имени, потому что встроенная функция callable() (см. раздел 8.1 лаб. раб. №1) возвращают значение True:

>>> print (callable (fibo))
True,

и получить 10 чисел Фибоначчи:

>>> print (fibo(10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Функция fibo() оформлена в виде файла ... \LAB6\fibo.py, имеет один параметр k, с помощью которого пользователь задает число необходимых ему чисел Фибоначчи. В строке документирования указано назначение функции и ее параметра.
Имеется несколько способов передачи значений параметрам функции:

· с помощью позиционных аргументов (см. подраздел 1.1.1);

· с помощью именнованных аргументов (см. подраздел 1.1.2);

· с помощью аргументов, имеющих значения по умолчанию (см. подраздел 1.1.3);

· с помощью аргументов, заданных списком (см. подраздел 1.1.4);

· с помощью аргументов, заданных словарем (см. подраздел 1.1.5).

 



Поделиться:


Последнее изменение этой страницы: 2021-11-27; просмотров: 170; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.144.40.90 (0.008 с.)