function.md 7.1 KB

~={green}Определения:=~

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

    def f():
        print("QWERTY")
    
    def f():
        print("ABC")
    
    f()
    f()
    
  • Любая функция в python возвращает значение. Значение возвращается при помощи оператора return. Если функция не содержит оператор return, то по умолчанию такая функция вернет значение None.

  • Функция должна выполнять только одну операцию. Она должна выполнять ее хорошо. И ничего другого она делать не должна. Если функция выполняет только те действия, которые находятся на одном уровне под объявленным именем функции, то эта функция выполняет одну операцию.

  • Будьте последовательны в выражениях возврата: либо все операторы return в функции должны возвращать выражение, либо ни один из них не должен. Если какой-либо оператор return возвращает выражение, то оставшиеся операторы return тоже должны явно возвращать значение, не смотря на то, что python по умолчанию возвращает None. Статья по оформлению [[https://pythonchik.ru/osnovy/imenovanie-v-python]]

~={green}Пример оформления простой функции:=~

# is - в названии функциии
# нет лишних return
def is_even(x):
    return x%2 == 0

# пример использования без лишних сравнений
number = int(input("Введите число: "))
while is_even(number):
	print(f'{number} является четным')
	number = int(input("Введите число: "))
print(f"Вы ввели нечетное число {number}, программа завершилась")

~={green}Возврат кортежа=~

# в return можно не ставить скобки, все равно будет возвращен кортеж
def calc_square_and_perimeter(a, b):
	retun a * b, 2 * (a + b)

~={green}Возврат списка=~

# в данном случае нужны скобки [ ]
def calc_square_and_perimeter(a, b):
	return [a * b, 2 * (a + b)]

~={green}Передача аргументов=~

  • При комбинированной передачи аргументов сначала должны быть указаны позиционные аргументы, а только потом именованные!
  • Параметры являются локальными переменными и они определяются в момент вызова функции. В параметры присваиваются ссылки на объекты, переданные в аргументы.
  • Параметры функции делятся на _обязательные_ и _необязательные_.
  • Никогда не используйте изменяемые объекты в качестве значений по умолчанию.
  • Значение по умолчанию вычисляется только один раз при определении функции.

~={green}Изменяемые объекты в качестве параметров по умолчанию=~

  • сперва присваивайте параметру значению None
  • внутри функции проверяйте, если параметр принимает None, значит создаем пустой изменяемый объект

    def append_to_list_2(value, my_list=None):
        if my_list is None:
            my_list = []
        my_list.append(value)
      print(my_list, id(my_list))
        return my_list
    

~={green}Множественное присваивание=~ Остальные значения сохраняются в виде списка с переменную "с"

a, b, *c = [1, True, 4, 6, 'hello ', 7, 9]
1, True, [4, 6, 'hello ', 7, 9]

a, *b, c = [1, True, 4, 6, 'hello ', 7, 9]
1, [True, 4, 6, 'hello ', 7], 9

a, b, *c = [1, True, 4, 6, 'hello ', 7, 9]
1, True, [4, 6, 'hello ', 7, 9]

a, *b, c = 'hello moto'
h ['e', 'l', 'l', 'o', ' ', 'm', 'o', 't'] o

a, *b, c = [1, 4]
1 [] 4

~={green}Передача переменного количество аргументов=~

def my_func(*args)
def my_func(**kargs)

# Необязательный аргумент после *args
def my_func(*args, foo=True)

# Объединенный вариант передачи аргументов
def my_func(a, b, *args, c, d=4, **kwargs):

В args будет ~={red}кортеж=~. В kwargs будет ~={red}словарь=~.

# При распаковке словаря передаются значения
def print_args(a, b, c=15):
    print(a, b, c)

dct = {'a': 5, 'b': 10}
print_args(**dct)

>>> 5, 10 15

# Распаковка при передачи списка и словаря
my_list =[5, 19, 23, 88]
my_dict = {'a': 11, 'b': 23}
item_sum(*my_list, **my_dict)

~={green}Как нельзя передавать аргументы=~ ~={red}Нельзя передавать позиционные аргументы после именованных!=~

def my_func(a, b, *args):
    print(f'{a=}, {b=}, {args=}')

# Будет ошибка при передаче аргументов по ключам
my_func(a=20, b=20, 30, 40, 50)

~={green}Только ключевые аргументы=~ Все параметры, которые стоят справа от * должны принимать значения только по ключу. Все параметры, которые стоят слева от / должны принимать значения только по позиции. * - только ~={magenta}ключевые=~ аргументы / - как ~={magenta}позиционные=~ так и ~={magenta}ключевые=~ аргументы

def my_func(*, a, b):
    print(f'{a=}, {b=}')

# Так передать можно
my_func(b=30, a=40)

# А так нельзя
my_func(10, b=20)