Как выяснилось, у некоторых начинающих питонистов, особенно у тех, кто ранее пользовался языками со статической типизацией, создается впечатление о том, что глобальные переменные в Python работают странно. Можно было бы вспомнить, что глобальные переменные — это зло и закрыть вопрос на этом. Но Python часто используется для прототипирования, где можно позволить себе это, а кроме того, развитая система пакетов и модулей в языке гарантирует чистоту глобального пространства имен (если, конечно, не пользоваться, import *). Поэтому, рассмотрим небольшой пример.
В языках со статической типизацией объявление переменной, как правило, отличается от оператора присваивания. В первой строке нашего примера для C-подобного языка происходит и объявление, и инициализация, а в третьей строке, в теле функции, только присваивание, что различается синтаксически. А для Python, и первая и третья строка синтаксически одинаковы. Если бы интерпретатор Python работал так же, как принято в C-подобных языках, было бы невозможно объявить локальную переменную с тем же именем, которое уже имеет глобальная переменная. Чтобы избежать подобных ситуаций, присваивание в Python всегда работает в самой локальной области видимости. Для нашего примера это аналогично тому, что мы бы написали int a = 7 в теле функции в левом столбике примера.
В результате мы получаем полезное свойство языка: он не позволяет случайно переприсвоить значение переменной из глобальной области видимости. Если все же надо изменить значение в глобальном контексте, можно воспользоваться ключевым словом global и результат получится ожидаемым:
На самом деле все немного сложнее, и для того, кто хочет разобраться подробнее, рекомендую почитать про правило LEGB.
Еще немного о Python:
Карринг и композиция в Python
Python: генерация паролей
Несколько примеров на list comprehension в Python
Генераторы Python и ленивые вычисления
Обход дерева каталогов в Python
Что-нибудь C-подобное | Python |
int a = 5; void f() { a = 7; } int main() { print (a); f(); print (a); return 0; } |
a = 5 def f(): a = 7 print a f() print a |
Результат: | Результат: |
5
7 |
5
5 |
В языках со статической типизацией объявление переменной, как правило, отличается от оператора присваивания. В первой строке нашего примера для C-подобного языка происходит и объявление, и инициализация, а в третьей строке, в теле функции, только присваивание, что различается синтаксически. А для Python, и первая и третья строка синтаксически одинаковы. Если бы интерпретатор Python работал так же, как принято в C-подобных языках, было бы невозможно объявить локальную переменную с тем же именем, которое уже имеет глобальная переменная. Чтобы избежать подобных ситуаций, присваивание в Python всегда работает в самой локальной области видимости. Для нашего примера это аналогично тому, что мы бы написали int a = 7 в теле функции в левом столбике примера.
В результате мы получаем полезное свойство языка: он не позволяет случайно переприсвоить значение переменной из глобальной области видимости. Если все же надо изменить значение в глобальном контексте, можно воспользоваться ключевым словом global и результат получится ожидаемым:
a = 5 def f(): global a a = 7 print a f() print a
На самом деле все немного сложнее, и для того, кто хочет разобраться подробнее, рекомендую почитать про правило LEGB.
Еще немного о Python:
Карринг и композиция в Python
Python: генерация паролей
Несколько примеров на list comprehension в Python
Генераторы Python и ленивые вычисления
Обход дерева каталогов в Python
Комментариев нет:
Отправить комментарий