Хотя этот график сложен, он используется для демонстрации многих базовых концепций, которые мы разработали до сих пор.
Имена привязаны к значениям, и они распространяются на множество локальных фреймов. Локальные фреймы находятся над единственным глобальным фреймом, который содержит общие имена. Выражение представляет собой древовидную структуру, и при каждом вызове подвыражения, содержащего пользовательскую функцию, необходимо расширять окружение.
Все эти механизмы гарантируют, что имена правильно разрешаются в выражениях к правильным значениям. Этот пример показывает, почему наша модель требует введённой сложности. Все три локальных фрейма содержат привязку имени x. Однако это имя привязано к разным значениям в разных фреймах. Локальный фрейм отделяет эти имена.
1.3.4 Локальное имя
Одна из деталей реализации функции заключается в том, что выбор имён формальных параметров разработчиком не должен влиять на поведение функции. Поэтому следующие функции должны вести себя одинаково:
>>> def square(x):
return mul(x, x)
>>> def square(y):
return mul(y, y)
Этот принцип — то есть функция не должна зависеть от выбора имён параметров разработчиком — имеет важные последствия для языков программирования. Простейшим следствием является то, что имена параметров функции должны быть сохранены в локальной области видимости функции.
Если параметр не находится в локальной области соответствующей функции, параметр x функции square может привести к путанице с параметром x функции sum_squares. Строго говоря, это не проблема: привязки x в различных локальных фреймах не связаны друг с другом. Наша вычислительная модель имеет строгий дизайн, чтобы гарантировать эту независимость.
Мы говорим, что область действия локального имени ограничена определением функции, которая его использует. Когда имя больше не доступно, оно выходит за рамки области действия. Поведение области действия не является новым фактом нашей модели, а скорее результатом работы среды.
1.3.5 Практическое руководство: выбор имён
Изменчивость имён не означает, что имена формальных параметров полностью не важны. Напротив, выбор хороших имён функций и параметров необходим для понятности определения функций человеком.
Следующие рекомендации вытекают из Руководства по стилю кода Python и могут служить руководством для всех (не мятежных) программистов Python. Некоторые общие соглашения облегчают общение между членами сообщества. Соблюдение этих соглашений имеет некоторые побочные эффекты, и я обнаружу, что ваш код становится внутренне согласованным.
Периодически пересматривая эти рекомендации в своих программах, ваши имена скоро станут очень Python-изированными.
1.3.6 Как абстрактная функция
Хотя sum_squares очень прост, он демонстрирует самую мощную особенность пользовательских функций. Функция sum_squares использует определение функции square, но зависит только от отношения между входным параметром и выходным значением, определённым в square.
Можно написать sum_squares, не беспокоясь о том, как вычислить квадрат числа. Детали вычисления квадратов скрыты и могут быть рассмотрены позже. Действительно, для sum_squares square не является конкретной функцией, а является своего рода абстракцией функции, известной как функциональная абстракция. На этом уровне абстракции любая функция, способная вычислять квадраты, эквивалентна.
Таким образом, учитывая только возвращаемые значения, следующие две функции для вычисления квадратов неразличимы. Каждая принимает числовой параметр и производит квадрат этого числа в качестве возвращаемого значения.
>>> def square(x):
return mul(x, x)
>>> def square(x):
return mul(x, x-1) + x
Другими словами, определение функции должно скрывать детали. Пользователь функции может не иметь возможности написать функцию самостоятельно, но может получить её от других программистов как «чёрный ящик». Пользователю не нужно знать, как это реализовано, чтобы вызвать его. Библиотеки Python обладают этим свойством. Многие разработчики используют функции, определённые здесь, но редко смотрят на их реализацию. Фактически, реализация многих библиотек Python написана не полностью на Python, а на языке C.
1.3.7 Операторы
Арифметические операторы (такие как + и -) предоставляют средства комбинирования в нашем первом примере. Но нам также необходимо определить процесс оценки для выражений, содержащих эти операторы.
Каждое выражение с инфиксным оператором в Python имеет свой собственный процесс оценки, но вы обычно можете думать о них как о сокращении для вызова выражений. Когда вы видите
>>> 2 + 3
5
можно просто подумать об этом как
>>> add(2, 3)
5
Инфиксные обозначения могут быть вложенными, как и вызовы выражений. Python использует обычные математические правила для приоритета операторов, которые направляют интерпретацию сложных выражений с несколькими операторами.
>>> 2 + 3 * 4 + 5
19
даёт тот же результат оценки, что и
>>> add(add(2, mul(3, 4)) , 5)
19
Вложенные версии вызовов выражений более очевидны. Python также позволяет заключать подвыражения в скобки, чтобы переопределить обычные правила приоритета или сделать структуру вложения выражений более очевидной:
>>> (2 + 3) * (4 + 5)
45
и
>>> mul(add(2, 3), add(4, 5))
45
дают одинаковый результат оценки.
Вы должны свободно использовать эти операторы и круглые скобки в своих программах. Для простых арифметических операций Python обычно предпочитает операторы, а не вызовы выражений.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )