- scope.py
- scope.py
#!# =======
#!# Scope
#!# =======
#!#
#!# This page contains a memo on scope.
####################################################################################################
from Tools import *
####################################################################################################
#!# Upper scope
#!# -----------
#!# Attributes are local to the "__main__" Python file or a module
a_global = 1 # in fact local to upper scope
print(a_global)
#o#
#!# _ prefixed attributes are privates by convention
_a_private_global = 2
#!# Module Scope
#!# ~~~~~~~~~~~~
#?# Fixme: #i# don't work
#!# Let a module :file:`ModuleA/__init__.py`
#itxt# ModuleA/__init__.py
import ModuleA
#o#
#!# Loops
#!# ~~~~~
for i in range(10):
# i is local to the upper scope
pass
print('i' in globals())
print('last i is', i)
#o#
#!# With statement
#!# ~~~~~~~~~~~~~~
with open(__file__) as fh:
# fh is local to the upper scope
print(type(fh))
print(type(fh))
#o#
#!# Test for main
#!# -------------
if __name__ == '__main__':
print('This file is main')
#!# Function scope
#!# --------------
another_global = 1
def foo():
tmp_local = 1 # temporary attribute in function scope
another_global = 2 # idem
# global id1, id2, ...
global a_global # use attribute defined at top level (global)
print_function('foo', a_global, another_global)
try:
print(tmp_local)
except NameError as exception:
print(exception)
foo()
#o#
def outside():
tmp_local = "outside"
def inside():
tmp_local = "inside"
print_function('inside', tmp_local)
inside()
print_function('outside', tmp_local)
outside()
#o#
def outside():
tmp_local = "outside"
def inside():
# nonlocal id1, id2, ...
nonlocal tmp_local # # use attribute defined at upper level
tmp_local = "inside"
print_function('inside', tmp_local)
inside()
print_function('outside', tmp_local)
outside()
#o#
#!# We can attach attributes to function
foo.attribute = 1
#!# Class scope
#!# -----------
class Foo:
# We can execute codes in class declaration !
print('building Foo')
attribute = 1 # local attribute in class scope
# _ prefixed attributes are privates by convention
_private_attribute = 2
# __ prefixed attributes are prefixed by class name
# "__foo_attribute" is mangled to "Foo__foo_attribute"
__foo_attribute = 3
def __init__(self):
print_method(self, '__init__')
# This method cannot be overridden in subclasses
def __method(self):
print_method('Foo', '__method', self)
def method(self):
print_method(self, 'method')
self.__method() # call Foo__foo_attribute
#!# We can complete class later
Foo.attribute = 2
def another_method(self):
print_method(self, 'another_method')
Foo.another_method = another_method
#o#
obj = Foo()
obj.method()
obj.another_method()
#o#
class Bar(Foo):
def __method(self):
print_method('Bar', '__method', self)
obj = Bar()
obj.method()
#o#
3.3.15. Scope¶
This page contains a memo on scope.
from Tools import *
3.3.15.1. Upper scope¶
Attributes are local to the “__main__” Python file or a module
a_global = 1 # in fact local to upper scope
print(a_global)
1
_ prefixed attributes are privates by convention
_a_private_global = 2
3.3.15.1.1. Module Scope¶
Let a module ModuleA/__init__.py
#skip#
print('Building ModuleA')
try:
print(a_global)
except NameError as exception:
print(exception)
try:
print(__main__.a_global) # wrong
except NameError as exception:
print(exception)
import ModuleA
ModuleNotFoundError
3.3.15.1.2. Loops¶
for i in range(10):
# i is local to the upper scope
pass
print('i' in globals())
print('last i is', i)
True
last i is 9
3.3.15.1.3. With statement¶
with open(__file__) as fh:
# fh is local to the upper scope
print(type(fh))
print(type(fh))
NameError
3.3.15.2. Test for main¶
if __name__ == '__main__':
print('This file is main')
3.3.15.3. Function scope¶
another_global = 1
def foo():
tmp_local = 1 # temporary attribute in function scope
another_global = 2 # idem
# global id1, id2, ...
global a_global # use attribute defined at top level (global)
print_function('foo', a_global, another_global)
try:
print(tmp_local)
except NameError as exception:
print(exception)
foo()
name 'tmp_local' is not defined
@foo
1
2
def outside():
tmp_local = "outside"
def inside():
tmp_local = "inside"
print_function('inside', tmp_local)
inside()
print_function('outside', tmp_local)
outside()
@inside
'inside'
@outside
'outside'
def outside():
tmp_local = "outside"
def inside():
# nonlocal id1, id2, ...
nonlocal tmp_local # # use attribute defined at upper level
tmp_local = "inside"
print_function('inside', tmp_local)
inside()
print_function('outside', tmp_local)
outside()
@inside
'inside'
@outside
'inside'
We can attach attributes to function
foo.attribute = 1
3.3.15.4. Class scope¶
class Foo:
# We can execute codes in class declaration !
print('building Foo')
attribute = 1 # local attribute in class scope
# _ prefixed attributes are privates by convention
_private_attribute = 2
# __ prefixed attributes are prefixed by class name
# "__foo_attribute" is mangled to "Foo__foo_attribute"
__foo_attribute = 3
def __init__(self):
print_method(self, '__init__')
# This method cannot be overridden in subclasses
def __method(self):
print_method('Foo', '__method', self)
def method(self):
print_method(self, 'method')
self.__method() # call Foo__foo_attribute
We can complete class later
Foo.attribute = 2
def another_method(self):
print_method(self, 'another_method')
Foo.another_method = another_method
obj = Foo()
obj.method()
obj.another_method()
@Foo.__init__
@Foo.method
@Foo.__method
<__main__.Foo object at 0x7ff7d0a62c18>
@Foo.another_method
class Bar(Foo):
def __method(self):
print_method('Bar', '__method', self)
obj = Bar()
obj.method()
@Bar.__init__
@Bar.method
@Foo.__method
<__main__.Bar object at 0x7ff7d09bd4e0>