This expression has the appearance of a function but it returns and behaves like a dictionary representing the current global symbol table.
Invoke python on Unix and display information about globals():
$ python3.6
Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> type(globals())
<class 'dict'>
>>>
>>> globals()
{
'__name__' : '__main__',
'__doc__' : None,
'__package__' : None,
'__loader__' : <class '_frozen_importlib.BuiltinImporter'>,
'__spec__' : None,
'__annotations__': {},
'__builtins__' : <module 'builtins' (built-in)>
}
# Braces '{}' enclose a dictionary.
# Each key '__name__', '__doc__', '__package__' .... is a string.
# Each value '__main__', None, None, .... may or may not be a string. Most values above are not strings.
>>> quit()
$
When you invoke python interactively, the above global variables are predefined. Unless you really know what you are doing,
it is recommended that you do not attempt to change any of the predefined global variables.
Python source file tmp1.py:
$ head -3 tmp1.py
# tmp1.py
print ('\n'.join([ ((v + (' '*30))[:20] + str(v1)) for v in globals() for v1 in (globals()[v],) ]))
exit (0)
$
When python is invoked by executing python source file tmp1.py on Unix, the following global variables are predefined:
$ python3.6 tmp1.py
__name__ __main__
__doc__ None
__package__ None
__loader__ <_frozen_importlib_external.SourceFileLoader object at 0x10189e2b0>
__spec__ None
__annotations__ {}
__builtins__ <module 'builtins' (built-in)>
__file__ tmp1.py
__cached__ None
$
The values '__file__', '__cached__' have been added and value '__loader__' has changed.
Within the listcomp above:
- Variables
v, v1 are local to the listcomp and do not appear in the list of global symbols. This is why a listcomp was used.
- Each value has been converted to
str for printing. (Actually so that method '\n'.join(....) will work properly.)
Accessing dictionary globals()
edit
>>> v1 = 6 ; t1 = (1,2,3)
>>> globals()
{
'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'v1': 6,
't1': (1, 2, 3)
}
>>>
>>> v1 in globals()
False
>>> 'v1' in globals() # Each key is a string.
True
>>> 'v2' in globals() # Use this feature to determine whether or not global variable v2 exists.
False
>>>
>>> s1 = 'v1'
>>> globals()
{
# 7 predefined global variables as above.
'v1': 6,
't1': (1, 2, 3),
's1': 'v1'
}
>>> s1 in globals()
True
>>> globals()[s1]
6
>>> 's1' in globals()
True
>>> globals()['s1']
'v1'
>>>
To delete a global variable:
>>> v3 = [1,2,3]
>>> v3
[1, 2, 3]
>>> del globals()['v3']
>>> v3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'v3' is not defined
>>>
|
|
Creating global variables
edit
During execution of python code global variables that did not exist in the code may be created.
>>> v3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'v3' is not defined
>>>
>>> for num in range (3,7) :
... s1 = 'v' + str(num)
... globals()[s1] = num**2
...
>>> v3
9
>>>
>>> globals()
{
# 7 predefined variables.
'num': 6,
's1' : 'v6',
'v3' : 9,
'v4' : 16,
'v5' : 25,
'v6' : 36
}
>>>
>>> v3,v4,v5,v6
(9, 16, 25, 36)
>>>
|
>>> import decimal
>>> globals()
{
# ....
'decimal': <module 'decimal' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/decimal.py'>
}
>>> d1 = Decimal(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Decimal' is not defined
>>> d1 = decimal.Decimal(3);d1
Decimal('3')
>>> D = decimal.Decimal
>>> d2 = D(6);d2
Decimal('6')
>>>
Change syntax of import statement slightly and try again:
>>> from decimal import *
>>>
>>> globals()
'__name__' '__main__'
'__doc__' None
'__package__' None
'__loader__' <class '_frozen_importlib.BuiltinImporter'>
'__spec__' None
'__annotations__' {}
'__builtins__' <module 'builtins' (built-in)>
'getcontext' <built-in function getcontext>
'setcontext' <built-in function setcontext>
'localcontext' <built-in function localcontext>
'Decimal' <class 'decimal.Decimal'>
'Context' <class 'decimal.Context'>
'DecimalTuple' <class 'decimal.DecimalTuple'>
'DecimalException' <class 'decimal.DecimalException'>
'Clamped' <class 'decimal.Clamped'>
'Rounded' <class 'decimal.Rounded'>
'Inexact' <class 'decimal.Inexact'>
'Subnormal' <class 'decimal.Subnormal'>
'Underflow' <class 'decimal.Underflow'>
'Overflow' <class 'decimal.Overflow'>
'DivisionByZero' <class 'decimal.DivisionByZero'>
'FloatOperation' <class 'decimal.FloatOperation'>
'InvalidOperation' <class 'decimal.InvalidOperation'>
'ConversionSyntax' <class 'decimal.ConversionSyntax'>
'DivisionImpossible' <class 'decimal.DivisionImpossible'>
'DivisionUndefined' <class 'decimal.DivisionUndefined'>
'InvalidContext' <class 'decimal.InvalidContext'>
'DefaultContext' Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0,
flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
'HAVE_THREADS' True
'BasicContext' Context(prec=9, rounding=ROUND_HALF_UP, Emin=-999999, Emax=999999, capitals=1, clamp=0,
flags=[], traps=[Clamped, InvalidOperation, DivisionByZero, Overflow, Underflow])
'ExtendedContext' Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[])
'MAX_PREC' 999999999999999999
'MAX_EMAX' 999999999999999999
'MIN_EMIN' -999999999999999999
'MIN_ETINY' -1999999999999999997
'ROUND_UP' 'ROUND_UP'
'ROUND_DOWN' 'ROUND_DOWN'
'ROUND_CEILING' 'ROUND_CEILING'
'ROUND_FLOOR' 'ROUND_FLOOR'
'ROUND_HALF_UP' 'ROUND_HALF_UP'
'ROUND_HALF_DOWN' 'ROUND_HALF_DOWN'
'ROUND_HALF_EVEN' 'ROUND_HALF_EVEN'
'ROUND_05UP' 'ROUND_05UP'
>>>
>>> d1 = Decimal(6); d1 # With this syntax class Decimal is defined as global variable.
Decimal('6')
>>>
>>> type(globals()['MIN_ETINY'])
<class 'int'>
>>> type(globals()['DefaultContext'])
<class 'decimal.Context'>
>>> type(globals()['DivisionByZero'])
<class 'type'>
>>>
>>> type(globals()['ROUND_HALF_UP'])
<class 'str'>
>>> globals()['ROUND_HALF_UP'] == 'ROUND_HALF_UP' # In this case key and value are the same.
True
>>>
To view the contents of globals(), simply enter:
>>> from decimal import *
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'getcontext': <built-in function getcontext>, 'setcontext': <built-in function setcontext>, 'localcontext': <built-in function localcontext>, 'Decimal': <class 'decimal.Decimal'>, 'Context': <class 'decimal.Context'>, 'DecimalTuple': <class 'decimal.DecimalTuple'>, 'DecimalException': <class 'decimal.DecimalException'>, 'Clamped': <class 'decimal.Clamped'>, 'Rounded': <class 'decimal.Rounded'>, 'Inexact': <class 'decimal.Inexact'>, 'Subnormal': <class 'decimal.Subnormal'>, 'Underflow': <class 'decimal.Underflow'>, 'Overflow': <class 'decimal.Overflow'>, 'DivisionByZero': <class 'decimal.DivisionByZero'>, 'FloatOperation': <class 'decimal.FloatOperation'>, 'InvalidOperation': <class 'decimal.InvalidOperation'>, 'ConversionSyntax': <class 'decimal.ConversionSyntax'>, 'DivisionImpossible': <class 'decimal.DivisionImpossible'>, 'DivisionUndefined': <class 'decimal.DivisionUndefined'>, 'InvalidContext': <class 'decimal.InvalidContext'>, 'DefaultContext': Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]), 'HAVE_THREADS': True, 'BasicContext': Context(prec=9, rounding=ROUND_HALF_UP, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[Clamped, InvalidOperation, DivisionByZero, Overflow, Underflow]), 'ExtendedContext': Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[]), 'MAX_PREC': 999999999999999999, 'MAX_EMAX': 999999999999999999, 'MIN_EMIN': -999999999999999999, 'MIN_ETINY': -1999999999999999997, 'ROUND_UP': 'ROUND_UP', 'ROUND_DOWN': 'ROUND_DOWN', 'ROUND_CEILING': 'ROUND_CEILING', 'ROUND_FLOOR': 'ROUND_FLOOR', 'ROUND_HALF_UP': 'ROUND_HALF_UP', 'ROUND_HALF_DOWN': 'ROUND_HALF_DOWN', 'ROUND_HALF_EVEN': 'ROUND_HALF_EVEN', 'ROUND_05UP': 'ROUND_05UP'}
>>>
While the above information is 100% accurate, without formatting it's not very helpful.
Basic formatted output can be accomplished with:
>>> from decimal import *
>>> for v in globals() : print (v, ' ', globals()[v])
...
__name__ __main__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
>>> v = 0
>>> for v in globals() : print (v, ' ', globals()[v])
...
__name__ __main__
__doc__ None
__package__ None
__loader__ <class '_frozen_importlib.BuiltinImporter'>
...............................
ROUND_HALF_UP ROUND_HALF_UP
ROUND_HALF_DOWN ROUND_HALF_DOWN
ROUND_HALF_EVEN ROUND_HALF_EVEN
ROUND_05UP ROUND_05UP
v v
>>>
The above adds variable 'v' and it does not show which of the above values are strings.
Try again using a listcomp:
>>> from decimal import *
>>> print ( '\n'.join(
... [
... sx
... for keys in ([ v for v in globals() ], )
... for len1 in ( sorted( [ len(k) for k in keys ] )[-1]+4, )
... for k in keys
... for v in (globals()[k],)
... for k1 in ( ('**error**', "'" + k + "'")[isinstance(k,str)], )
... for single_quote in ( ("", "'")[isinstance(v,str)], )
... for v1 in ( single_quote + str(v) + single_quote, )
... for sx in ( (k1 + (' '*len1))[:len1] + v1, )
... ]
... ))
'__name__' '__main__'
'__doc__' None
'__package__' None
'__loader__' <class '_frozen_importlib.BuiltinImporter'>
'__spec__' None
'__annotations__' {}
'__builtins__' <module 'builtins' (built-in)>
................................................
'ROUND_DOWN' 'ROUND_DOWN'
'ROUND_CEILING' 'ROUND_CEILING'
'ROUND_FLOOR' 'ROUND_FLOOR'
'ROUND_HALF_UP' 'ROUND_HALF_UP'
'ROUND_HALF_DOWN' 'ROUND_HALF_DOWN'
'ROUND_HALF_EVEN' 'ROUND_HALF_EVEN'
'ROUND_05UP' 'ROUND_05UP'
>>>
|
|
Global communication
edit
globals() may be used for communication between nested functions. In the code below, function2() is defined within function1()
and function3() is defined within function2().
By means of globals(), function3() can access the local variables of both function1() and function2():
def function1() :
def function2() :
def function3() :
I1 = 6
globals()['f3locals'] = dict(locals())
print ('''
function3():
f1locals = {}
f2locals = {}
f3locals = {}
'''.format(
globals()['f1locals'],
globals()['f2locals'],
globals()['f3locals'],
))
del globals()['f3locals']
I1 = 4
globals()['f2locals'] = dict(locals())
function3()
del globals()['f2locals']
I1 = 2
globals()['f1locals'] = dict(locals())
function2()
del globals()['f1locals']
function1()
for v in ('f1locals', 'f2locals', 'f3locals') :
print (v in globals())
function3():
f1locals = {'I1': 2, 'function2': <function function1.<locals>.function2 at 0x102164158>}
f2locals = {'I1': 4, 'function3': <function function1.<locals>.function2.<locals>.function3 at 0x1021641e0>}
f3locals = {'I1': 6}
False
False
False
Notice that:
function2 is local to function1, and
function3 is local to function2.
|
|