Добрый вечер.
def make_adder(num: int) -> int:
def add(x: int):
return x + num
return add
»»» plus_3 = make_adder(3)
»»»plus_3(4)
Out:7
Почему получилось передать в конструктор 3 и вообще откуда он появился, если я его не прописывал?
Это называется "замыкание", или "фабричная функция".
Вызвав make_adder с аргументом, ты создал объект функции add, в которую из области видимости make_adder попал аргумент, переданный при первом вызове.
make_adder вернула тебе объект функции с сохраненным аргументом, после чего ты успешно вызвал эту функцию, передав ей еще один аргумент.