- Способы передачи:
- Позиционный: Аргументы передаются в том порядке, в котором определены параметры.
def func(a, b, c): print(a, b, c) func(1, 5, 7) # Вывод: 1 5 7
- Именованный (по ключу): Аргументы передаются с указанием имени параметра. Порядок не важен.
func(b=20, c=15, a=5) # Вывод: 5 20 15
- Комбинированный: Сначала позиционные, затем именованные.
func(2, c=10, b=20) # Вывод: 2 20 10 # Ошибка: func(c=10, b=20, 2) # Позиционный после именованных
- Позиционный: Аргументы передаются в том порядке, в котором определены параметры.
- Типы параметров функции:
- Обязательные: Параметры без значений по умолчанию. Должны быть переданы при вызове.
def add(a, b): # a и b - обязательные return a + b
- Необязательные (со значением по умолчанию): Определяются с . Если аргумент для них не передан при вызове, используется значение по умолчанию. Должны идти после обязательных параметров.
def greet(name, greeting="Hello"): # greeting - необязательный print(f"{greeting}, {name}!") greet("Alice") # Вывод: Hello, Alice! greet("Bob", "Hi") # Вывод: Hi, Bob!
- Проблема изменяемых объектов в качестве значений по умолчанию: Значение по умолчанию создается один раз при определении функции. Если это изменяемый объект (список, словарь), его изменения будут сохраняться между вызовами.
# Неправильно: def append_to_list_bad(value, my_list=[]): my_list.append(value) print(my_list) append_to_list_bad(10) # Вывод: [10] append_to_list_bad(25) # Вывод: [10, 25] (!!!) append_to_list_bad(37) # Вывод: [10, 25, 37] (!!!) # Правильно: def append_to_list_good(value, my_list=None): if my_list is None: # Создаем новый список, если нужно my_list = [] my_list.append(value) print(my_list) append_to_list_good(10) # Вывод: [10] append_to_list_good(25) # Вывод: [25] append_to_list_good(37) # Вывод: [37]
- Обязательные: Параметры без значений по умолчанию. Должны быть переданы при вызове.
*args
и**kwargs
:- Оператор
*
(упаковка/распаковка позиционных):- Упаковка (в определении функции):
*args
собирает все лишние позиционные аргументы в кортежargs
.def sum_all(*args): # args - кортеж (1, 2, 3, 4) print(args) total = 0 for num in args: total += num return total print(sum_all(1, 2, 3, 4)) # Вывод: (1, 2, 3, 4) \n 10
- Распаковка (при вызове функции):
*iterable
распаковывает элементыiterable
как отдельные позиционные аргументы.nums = [1, 5, 7] func(*nums) # Эквивалентно func(1, 5, 7) s = [4, 10] print(list(range(*s))) # Эквивалентно range(4, 10) -> [4, 5, 6, 7, 8, 9]
- Распаковка при присваивании:
a, b, *c = [1, True, 4, 6, 'hello ', 7, 9] # a=1, b=True, c=[4, 6, 'hello ', 7, 9] a, *b, c = [1, True, 4, 6, 'hello ', 7, 9] # a=1, b=[True, 4, 6, 'hello ', 7], c=9 *a, b, c = [1, True, 4, 6, 'hello ', 7, 9] # a=[1, True, 4, 6, 'hello '], b=7, c=9
- Упаковка (в определении функции):
- Оператор
**
(упаковка/распаковка именованных):- Упаковка (в определении функции):
**kwargs
собирает все лишние именованные аргументы в словарьkwargs
.def print_info(**kwargs): # kwargs - словарь {'name': 'Alice', 'age': 30} print(kwargs) for key, value in kwargs.items(): print(f"{key}: {value}") print_info(name="Alice", age=30, city="New York") # Вывод: {'name': 'Alice', 'age': 30, 'city': 'New York'} # name: Alice # age: 30 # city: New York
- Распаковка (при вызове функции):
**dictionary
распаковывает пары ключ-значение словаря как отдельные именованные аргументы.params = {'b': 20, 'c': 15, 'a': 5} func(**params) # Эквивалентно func(a=5, b=20, c=15)
- Упаковка (в определении функции):
- Общий порядок параметров:
def func(pos_only, /, pos_or_kw, *, kw_only, **kwargs):
(Позиционные → Позиционные или именованные →*args
→ Только именованные →**kwargs
) Пример:def combined_func(a, b=10, *args, c, **kwargs): print(f"a={a}, b={b}, args={args}, c={c}, kwargs={kwargs}") combined_func(1, 2, 'x', 'y', c=3, d=4, e=5) # Вывод: a=1, b=2, args=('x', 'y'), c=3, kwargs={'d': 4, 'e': 5}
- Оператор
〰〰〰 𓆝 𓆟 𓆞 𓆝 𓆟 𓆝 𓆟 𓆞 〰〰〰