-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathunit2_lesson_07_understanding_scopes.py
More file actions
146 lines (103 loc) · 4 KB
/
Copy pathunit2_lesson_07_understanding_scopes.py
File metadata and controls
146 lines (103 loc) · 4 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
__author__ = 'Kalyan'
notes = '''
Scopes and namespaces govern the accessibility rules and lifetime of python variables.
Namespaces is a mapping of names to objects. Each python block creates a new namespace. The 3 main
python blocks are modules (files), functions and classes.
An object can have many names in the same namespace
An object can have names in different namespaces.
Scope is a textual area in which a variable can be directly accessible by its name.
Variable which are bound (created) in a block are called local variables in that block
Variables which are scoped to the the whole file (module) are called global
Variables which are scoped to outer functions (in case of nested functions) are called non-local or free.
Pre-lesson reading material: http://effbot.org/zone/python-objects.htm
'''
import inspect
import symtable
from placeholders import *
count = 10
#used to by pass any local shadow variables.
def get_global_count():
return count
def test_scope_basic():
local_names = get_locals(test_scope_basic)
value = count
assert __ == ('value' in local_names)
assert __ == ('value' in global_names)
assert __ == ('count' in local_names)
assert __ == ('count' in global_names)
assert __ == value
def test_scope_undefined_variable():
local_names = get_locals(test_scope_undefined_variable)
try:
my_name = name #name variable is not in local or global scope
except __ : # fill up the exception
pass
assert __ == ('my_name' in local_names)
assert __ == ('name' in local_names)
assert __ == ('name' in global_names)
def test_variable_shadow():
local_names = get_locals(test_variable_shadow)
count = 20
assert __ == ('count' in local_names)
assert __ == ('count' in global_names)
assert __ == count
assert __ == get_global_count()
def test_global_write():
local_names = get_locals(test_global_write)
global count # declare that we want to use the read/write to global count
count = 30
try:
assert __ == ('count' in local_names)
assert __ == ('count' in global_names)
assert __ == count
assert __ == get_global_count()
finally:
count = 10 #reset to original value
def test_scope_is_bound_at_definition_time():
local_names = get_locals(test_scope_is_bound_at_definition_time)
assert __ == ('count' in local_names)
assert __ == ('count' in global_names)
try:
value = count
count = 30
except __: # what happens when you read a variable before initializing it?
#print ex #uncomment after you fill up above
assert __
finally:
count = 20
assert __ == count
assert __ == get_global_count()
def test_scope_writing_globals():
local_names = get_locals(test_scope_writing_globals)
assert __ == ('count' in local_names)
assert __ == ('count' in global_names)
global count
try:
count = 40
assert __ == count
assert __ == get_global_count()
finally:
count = 10
assert __ == get_global_count()
notes_2 = """
Read up on names and scopes sections here (skip the portion on classes for now):
http://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces
https://docs.python.org/3/reference/executionmodel.html#naming
"""
three_things_i_learnt = """
-
-
-
"""
#helper functions which get the variables in locals and globals using the compiler's symbol tables.
def get_locals(func):
source = inspect.getsource(func)
top = symtable.symtable(source, "<string>", "exec")
func = top.get_children()[0] #since we are passing only the func code.
return func.get_locals()
def get_globals():
module = inspect.getmodule(get_globals)
source = inspect.getsource(module)
top = symtable.symtable(source, "<string>", "exec")
return top.get_identifiers()
global_names = get_globals()