-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvariables.py
More file actions
150 lines (125 loc) · 9.57 KB
/
variables.py
File metadata and controls
150 lines (125 loc) · 9.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------------
# Copyright (c) 2015 Artur Eganyan
#
# This work is provided "AS IS", WITHOUT ANY WARRANTY, express or implied.
#-------------------------------------------------------------------------------
# Кратко:
# - любая переменная - это просто имя, ссылающееся на объект
# - инструкция "имя = объект" копирует ссылку на объект
# - переменная существует в пределах блока, в котором она создана
# - блок - это часть кода, выполняемая как отдельное целое: модуль, функция, описание класса, динамический код
# - переменная всегда является локальной для своего блока и свободной для чужого
# - переменная также является глобальной, если она создана в модуле
# - инструкция "переменная = значение" создает/меняет локальную переменную
# - совокупность пар "имя -> объект" называется пространством имен, обычно это словарь
# - имя, указанное после точки ("объект.имя"), считается атрибутом объекта
# (Ниже написано немного упрощенное представление, без терминов вроде
# "область видимости" и "окружение". Про них есть немного в конце заметки.)
#
# Переменная в python - это просто имя, указывающее на объект (ссылка на
# объект). Операция присваивания "имя = объект" копирует ссылку на объект,
# а не сам объект. Переменная существует в пределах блока кода, в котором
# она была создана (связана с объектом).
#
# Блок - это часть кода, выполняемая как отдельное целое: модуль, функция,
# описание класса, а также динамически созданный код (eval, exec, execfile,
# input, команды в интерактивном режиме и переданные интерпретатору через
# консоль). Конструкции if, for, while, try и т.п. блоками не являются.
#
# Переменная доступна по имени в своем блоке и во всех вложенных в него
# блоках. Исключение: переменные, созданные в описании класса, недоступны
# во вложенных блоках (в частности - в методах класса).
#
# Переменная является локальной для блока, в котором она создана. Кроме того,
# переменная, созданная в модуле, считается глобальной. Переменная,
# используемая в блоке, но не созданная там, считается свободной в этом блоке.
#
# Присваивание "имя = значение" создает/изменяет локальную переменную.
# Если в этом блоке имя объявлено через global, будет изменена глобальная
# переменная.
#
# Отображение имен переменных в объекты называется пространством имен
# (namespace) и обычно хранится в словарях, отдельно для каждого блока -
# для модуля, вызова функции, описания класса. Но это зависит от реализации
# python, и не все словари доступны в явном виде (например, словари модуля
# и класса доступны, а словарь вызова функции - нет).
#
# Имя, указанное после точки ("объект.имя"), считается атрибутом объекта.
# Такой объект должен поддерживать операцию обращения к атрибутам. Обычно
# атрибут является элементом в словаре. Он может быть и переменной - например,
# глобальной переменной модуля ("модуль.переменная").
#
# Замечание: "обращение к переменной" и "обращение к имени переменной" обычно
# означают одно и то же. Но когда речь идет о "доступности" ("видимости")
# переменной, имеется в виду ее имя. Например, глобальная переменная "x"
# может быть недоступна по имени в функции, имеющей одноименную локальную
# переменную, но всегда доступна как атрибут модуля.
x = 1 # Глобальная переменная
def f():
print x # 1
y = 2 # Локальная переменная
def g():
print y # 2
g()
f()
# Важно: Если в блоке есть присваивание "имя = значение", переменная "имя"
# считается локальной _во всем_ блоке. Поэтому в примере ниже произойдет
# ошибка, т.к. x на момент использования еще не определена (не связана
# ни с каким объектом).
x = 1
def h():
print x # UnboundLocalError: local variable 'x' referenced before assignment
x = 2
#h()
# global должен стоять до первого использования переменной
def u():
global x
x = 2 # Глобальная x = 2
def g():
x = 3 # Локальная x = 3, т.к. в этом блоке не было global x
g()
u()
print x # 2
# Переменные, созданные в описании класса, недоступны по имени во вложенных
# блоках (в частности, в методах)
class A:
y = 1
def f( self ):
print A.y # 1, это обращение к атрибуту
#print y # NameError: global name 'y' is not defined
a = A()
a.f()
# Нельзя удалять переменную, которая используется во вложенном блоке
def t():
x = 1
def g():
print x
#del x # SyntaxError: can not delete variable 'x' referenced in nested scope
# Глобальная переменная ищется в пространстве имен модуля. Если там она
# не найдена, оттуда сначала берется переменная __builtins__ - в модуле
# __main__ это ссылка на модуль __builtin__, в других модулях это ссылка
# на его пространство имен. И далее переменная ищется там. __builtin__ -
# модуль со встроенными объектами.
print __builtins__ # <module '__builtin__' (built-in)>
print round # <built-in function round>, эта переменная будет найдена
# в __builtins__.__dict__
# Формальные понятия, которые показались несущественными:
#
# Блоки выполняются в кадрах (execution frame). Кадр содержит служебную
# информацию, необходимую для отладки, и определяет, где и как будет продолжено
# выполнение после завершения блока.
#
# У переменных есть область видимости (scope), определяющая, где они доступны
# по имени. Для функций и модулей область видимости включает все вложенные
# блоки, для описания классов - не включает. Область видимости определяется
# статически, на этапе чтения текста программы.
#
# При обращении к переменной, она ищется в текущей области видимости и всех
# внешних областях, доступных из текущего блока. Множество таких областей
# видимости называется окружением блока (environment).
#
# Область видимости и окружение - это по сути разные взгляды на одно и то же,
# т.е. на доступность имени переменной. Область видимости определяет все
# вложенные блоки, в которых к имени можно обратиться, а окружение - все
# внешние блоки, в которых имя может быть найдено при обращении.