======def (функция/метод)====== Последовательность инструкций, возвращающая некое значение. В функцию могут быть переданы ноль и более аргументов, которые могут использоваться в теле функции. Для возврата значения из функции используется инструкция return. Допускается использование нескольких return, в том числе для раннего выхода из функции. Функции без инструкции return (равно как и с нею, но без указания аргумента) всё равно возвращают результат — None. ====Определение функции==== Функцию можно определить при помощи ключевого слова **def**, за которым должно следовать название функции и список её формальных параметров в круглых скобках. На следующих строках, выделенное отступом слева, должно располагаться тело функции. Первой инструкцией в теле может быть литерал строки, который будет являться документацией для данной функции (строка документации — «docstring»). Некоторые утилиты и среды разработки используют такие строки для формирования интерактивной справки. Документировать код считается хорошим тоном. def do_work(work, reverse=False): """Выполняет работу. В случае удачного выполнения, возвращает True, иначе — False. :param list work: Список для работы. :param bool reverse: Флаг. Следует ли сделать работу в обратном порядке :rtype: bool """ В примере выше объявляется функция **do_work**, с формальными параметрами **work** и **reverse**. Функция задокументирована (испольузется формат описания сигнатуры **reStructuredText**). Кроме строки документации тело функции не содержит инструкций, тем не менее функция возвращает **None**. Определение функции описывает пользовательский «объект функции» и является исполняемой инструкцией. В ходе исполнения происходит связывание имени функции в текущем локальном пространстве имён (локальной символьной таблице) с «объектом функции» — обёрткой вокруг исполняемого кода функции. Объект функции содержит ссылку на текущее глобальное пространство имён, которое будет использовано при вызове функции. Объект функции может быть в последующем связан и с другим именем (это можно использовать для переименования функций и создания псевдонимов). Само определение функции не вызывает исполнения кода из тела функции. Код исполняется только при вызове функции. def print_yes(): print('yes') print_yes() # yes print_yes_alias = print_yes print_yes_alias() # yes Более того, ничто не мешает использовать «объект функции» как любой другой объект (например: передавать в функцию, использовать в качестве значения в словаре и т.п.). def print_yes(): print('yes') def print_no(): print('no') my_functions = [print_yes, print_no] for function in my_functions: # Переменная function будет содержать объект # функции. Его-то мы и вызываем в следующей строке. function() #yes #no В ходе исполнения функции формируется новая символьная таблица с локальными переменными функции: все назначения переменных оказываются в ней. При обращении к переменной, сначала производится попытка отыскать её в локальной символьной таблице, далее в таблицах обрамляющих функций, далее в глобальной таблице, и, наконец, в таблице встроенных имён. Ввиду вышесказанного ссылаться на глобальные переменные внутри функции можно, а присвоить им значение (без использования инструкции global) нельзя. MY_GLOBAL = 1 def set_global_1(): MY_GLOBAL = 2 def set_global_2(): global MY_GLOBAL MY_GLOBAL = 2 print(MY_GLOBAL) # 1 set_global_1() print(MY_GLOBAL) # 1 set_global_2() print(MY_GLOBAL) # 2 Аргументы, с которыми была вызвана функция, также оказываются в её локальной символьной таблице. В Питоне используется передача аргументов «по значению» (значением при этом всегда является ссылка на сам объект, но **не на его значение**). Однако, ввиду того, что в случаях, когда передаются изменяемые объекты, вызвавший увидит все изменения, сделанные вызываемым (например, при добавлении элементов в список), возможно лучше было бы назвать данный вид передачи **«передачей по ссылке на объект»**. def mutate_list(a_list): a_list.append(0) return True my_list = [1] print(my_list) # [1] mutate_list(my_list) # True print(my_list) # [1, 0] Когда функция вызывает другую функцию, для вызова создаётся новая локальная символьная таблица. ====Вложенные определения==== В Питоне можно вкладывать одно в другое не только определения функций (этим приёмом, в частости, пользуются при создании декораторов), но и классов (в случае необходимости). def outer_func(): # Определение функции внутри другой # функции. def inner_func(): return 'some' return inner_func() print(outer_func()) # some def get_my_class(): # Определение класса внутри определения # функции. class MyClass: my_attr = 1 return MyClass my_class = get_my_class() print(my_class.my_attr) # 1 ====позиционные аргументы==== Это аргументы, передаваемые в вызов в определённой последовательности (на определённых позициях), без указания их имён. Элементы объектов, поддерживающих итерирование, могут использоваться в качестве позиционных аргументов, если их распаковать при помощи *. def custom_sum(a, b, c, d): return a+b+c+d print(custom_sum(1, 2, 3, 4)) #10 ====Именованные аргументы==== Это аргументы, передаваемые в вызов при помощи имени (идентификатора), либо словаря с его распаковкой при помощи **. def custom_sum(a, b=0, c=0, d=0): return a+b+c+d print(custom_sum(1)) #1 print(custom_sum(1, 3)) #4 print(custom_sum(1, c=1)) #2 ====Переменное количество аргументов==== def custom_sum(*args): sum = 0 for i in args: sum +=i return sum print(custom_sum(1, 2, 3, 4)) def func(**kwargs): print(kwargs) func(a=1, b=4, c=45) # {'a': 1, 'b': 4, 'c': 45} def func2(a, x, *args, **kwargs): print(a) print(x) print(args) print(kwargs) func2(1, 2, 3, 4, b='test') # 1 # 2 # (3, 4) # {'b': 'test'} ====Документация к функциям==== def custom_sum(a, b): """ Возвращаем сумму аргументов a и b :param a параметр а :type a: int :param b параметр b :type b: int :return:return type int """ return a+b print(custom_sum(1, 2))