Ответ 1
Это поведение называется лексическим охватом. То, что вы описываете в # 2, называется динамическим охватом, хотя словесное описание вводит в заблуждение (вы говорите "охватывающие области", где "вызывающие функции" или "записи активации" были бы более точными).
Практически для каждого используемого языка используется лексическое охват, а не только Python. Это включает С# и ECMAScript/JavaScript (запрет eval
и with
), который, как я предполагаю, означает то, что вы подразумеваете под "ECMA-языками". Были языки, и некоторые из них все еще используются. Emacs Lisp является одним, а Perl предлагает как лексическое, так и динамическое масштабирование.
Обоснование лексического охвата не только для производительности (полное лексическое охват, включая закрытие, фактически имеет стоимость исполнения, см. проблемы с funcarg), это для простоты и надежности. Хотя это может быть удивительно, когда вы сначала изучаете язык, правила на самом деле мертвы, поэтому опытный программист может мгновенно сказать, какое использование идентификатора относится к какой области. Можно понять функции изолированно, поскольку на выполнение не влияет тот, кто называет эти функции и как они решили назвать свои переменные.