5. Функции.
Определение:
- Являются объектами (понятие function is a first-class citizen).
- Задаются с помощью ключевого слова def.
Возвращаемое значение:
- Тип возвращаемого значения не задаётся.
- Возвращаемое значение с помощью return.
- Если нет return, то вернёт None.
Аргументы:
- Аргументы передаются по ссылке.
- Типы аргументов не задаются.
- Именованные и позиционные аргументы.
- Именованные аргументы задаются со значением по-умолчанию и их можно указывать только когда явно нужно.
- Значение аргумента по-умолчанию создаётся только один раз - потенциальные проблемы (сохранённое состояние, общий контейнер).
- В определении параметров функции идут сначала позиционные, потом именованные аргументы.
- Собирающие аргументы
*args
и**kwargs
. *args
- все неперечисленные явно, но переданные позиционные аргументы будут помещены в аргумент-кортеж с указанным именем.**kwargs
- все неперечисленные явно, но переданные именованные аргументы будут помещены в аргумент-словарь с указанным именем.- Порядок: позиционные, именованные,
*args
,**kwargs
.
Локальные переменные:
- Определённые и используемые внутри каждой функции переменные считаются локальными и хранятся в отдельной таблице локальных символов.
- При обращении к переменной она сначала ищется в локальной области, а потом в глобальной.
- Чтобы писать в глобальные переменные из кода внутри функции надо сначала их явно пересчислить в выражении с ключевым словом global.
Документация:
- Документация с помощью docstring - https://www.python.org/dev/peps/pep-0257/
- Первым выражением может идти строковый литерал - docstring (documentation string).
- Можно получить из объекта функции из поля doc.
- Редакторы умеют показывать.
- Можно даже мини-тесты вставлять.
Код
# simple function def print_hello(): print "hello" def return_hello(): return "hello" # recursive function def dummy_factorial(value): if value == 0: return 1 else: return value * dummy_factorial(value - 1) print_hello() print return_hello() print dummy_factorial(3)
hello hello 6
# keyword argument def greet(name=None): if name is None: name = "stranger" print "Greetings, {name}".format(name=name)
greet() greet(name="user") Greetings, stranger Greetings, user
def show_params(first_param, second_param, *args, **kwargs): print type(args) print first_param, second_param, args print type(kwargs) print kwargs show_params("one", "two", "three", "four", first_named="named_one", second_named="named_two", third_named="named_three")
<type 'tuple'> one two ('three', 'four') <type 'dict'> {'second_named': 'named_two', 'third_named': 'named_three', 'first_named': 'named_one'}
# unpacking arguments (no always a good style, but sometimes useful) def show_params(first_param, second_param, third_param): print first_param, second_param, third_param elems = (3, 1, 2) show_params(*elems) print range(*elems)
3 1 2 []
d = {'a': 1, 'b': 2, 'c': 3} show_params(*d)
a c b
# unpacking kwargs def show_named_params(first_param="one", second_param="two", third_param="three"): print first_param, second_param, third_param d = {'first_param': 1, 'second_param': 2, 'third_param': 3} show_named_params(**d)
1 2 3
# zip-star magic elems_containers = ((1, 2, 3), (4, 5, 6), (7, 8, 9)) print zip(*elems_containers)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
# docstring def do_something(): """Short description of the function action More detailes description: may contain params, invariants, raised exceptions, return value and etc. """ pass print do_something.__doc__
Short description of the function action More detailes description: may contain params, invariants, raised exceptions, return value and etc.