-вызов функции:
def example_func(a, b, c=3): # a, b - позиционные параметры, c - ключевой параметр
pass
# Вызовы функции |
|
example_func(1, 2, 5) |
# можно : аргументы 1, 2, 5 распределяются |
# |
позиционно по параметрам 'a', 'b', 'c' |
example_func(1, 2) |
# можно : аргументы 1, 2 распределяются |
позиционно |
|
# |
по параметрам 'a', 'b' |
# |
в ключевой параметр 'c' аргумент |
# |
не передается, используется значение 3 |
example_func(a=1, b=2) # можно : аналогично example_func(1, 2),
#все аргументы передаются по ключу
example_func(b=2, a=1) # можно : аналогично example_func(a=1, b=2),
#если все позиционные параметры заполнены как
#ключевые аргументы, можно не соблюдать порядок
example_func(c=5, b=2, a=1) # можно : аналогично example_func(1, 2),
#аргументы передаются по ключу
example_func(1) |
# нельзя: для позиционного аргумента 'b' |
# |
не передается аргумент |
example_func(b=1) # нельзя: для позиционного аргумента 'a'
#не передается аргумент
Преимущества ключевых параметров:
нет необходимости отслеживать порядок аргументов; у ключевых параметров есть значение по умолчанию, которое можно не
передавать.
Пример функции со смешанными типами параметров приведен в листинге ниже.
Позиционные и ключевые параметры функций в Python
#Функция выдает запрос и
#- возвращает True в случае положительного ответа
#- возвращает False в случае отрицательного ответа
#- возвращает False если не получает ответ за [retries] попыток
def ask_user(prompt, retries=3, hint="Ответьте, ДА или НЕТ?"): while True:
30
retries -= 1
ok = input(prompt + " -> ").upper()
if ok in ("Д", "ДА"): return True
elif ok in ("Н", "НЕТ"): return False
if retries <= 0:
print("Не смог получить нужный ответ, считаю за отказ.") return False
print(hint)
#С ключевыми параметрами будут доступны также следующие
варианты:
#ask_user("Сохранить файл?", 0)
#ask_user("Сохранить файл?", retries=1)
#ask_user("Сохранить файл?", 2, "Жми Д или Н!!!")
#и др.
if ask_user("Сохранить файл?"): print("Сохранил!")
else:
print("Не сохранил.")
#-------------
#Пример вывода:
#Сохранить файл? -> Не знаю
#Ответьте, ДА или НЕТ?
#Сохранить файл? -> Да
#Сохранил!
1.Напишите программу вычисляющую факториал числа.
2.Напишите функцию с параметром по умолчанию.
3.Напишите функцию с ключевыми параметрами.
Вопросы для самопроверки
1.Как работают локальные и глобальные переменные в Python?
2.Как работает Лямда-функция в Python?
3.Как работает рекурсия в Python?
4.Как указать параметры по умолчанию в Python?
5.Какие бывают типы параметров в функциях в Python?
31
4. ДЕКОРАТОРЫ, ИСКЛЮЧЕНИЯ, ИТЕРАТОРЫ
Декораторы – обычные функции, которые принимают в качестве аргумента другую функцию.
def decorator(func):
def decorated(*args, **kwargs): print('before')
result = func(*args, **kwargs) print('after')
return result
return decorated def s(a,b):
return a+b
s = decorator(s) # "оборачиваем" функцию s(1, 2)
before 3 after
Более удобный способ обернуть функцию через символ @:
@decorator def m(a,b): print (a*b)
Запись вида
@f1
def func(): pass
эквивалентна def func(): pass func = f1(func)
Декораторов может быть несколько. В этом случае они «выполняются» сверху вниз.
@decorator
@timer
@pause
def func(x, y): return x + y
В декоратор можно передавать параметры:
def pause(t): def wrapper(f):
def tmp(*args, **kwargs):
32
time.sleep(t)
return f(*args, **kwargs) return tmp
return wrapper
@pause(2) def func(x, y): return x + y
Запись вида:
@f1(123)
def func(): pass
эквивалентна def func(): pass
func = f1(123)(func)
Использование декораторов в классах Использование декораторов на методах классов ничем не отличается от
использования декораторов на обычных функциях.
Для классов также есть предопределённые декораторы с именами staticmethod и classmethod. Они предназначены для задания статических методов и методов класса соответственно. Вот пример их использования:
class TestClass(object):
@classmethod def f1(cls):
print cls.__name__
@staticmethod def f2():
pass
class TestClass2(TestClass): pass
TestClass.f1() # печатает TestClass TestClass2.f1() # печатает TestClass2
a = TestClass2()
a.f1() # печатает TestClass2
Статический метод (обёрнутый декоратором staticmethod) в принципе соответствует статическим методам в C++ или Java. А вот метод класса – это нечто более интересное. Первым аргументом такой метод получает класс (не экземпляр!), это происходит примерно так же, как с обычными методами, которые первым аргументом получают референс на экземпляр класса. В случае,
33
когда метод класса вызывается на инстансе, первым параметром передаётся актуальный класс инстанса, это видно на примере выше: для порождённого класса передаётся именно порождённый класс!
Исключения Ошибки бывают 2 типов: ошибки синтаксиса и исключения.
>>> while True print('Hello world') File "<stdin>", line 1 while True print('Hello world')
SyntaxError: invalid syntax
Даже если выражение синтаксически корректно, ошибка может возникнуть во время выполнения. Такие ошибки называются "исключениями".
>>> 10*(1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero
>>> 4+spam*3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> '2'+2
Traceback (most recent call last): File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
Инструкции обработки исключений!
Исключения – по сути, являются событиями, способными изменить ход выполнения программы. Исключения в языке Python возбуждаются автоматически, когда программный код допускает ошибку, а также могут возбуждаться и перехватываться самим программным кодом.
Обрабатываются исключения четырьмя инструкциями:
try/except – перехватывает исключения, возбужденные интерпретатором или вашим программным кодом, и выполняет восстановительные операции.
try/finally – выполняет заключительные операции независимо от того, возникло исключение или нет.
raise – дает возможность возбудить исключение программно.
assert – дает возможность возбудить исключение программно, при выполнении определенного условия.
34