[Python-ideas] Allow function __globals__ to be arbitrary mapping not just dict

Steven D'Aprano steve at pearwood.info
Sun Mar 18 13:27:09 CET 2012


Currently, if you try to construct a function from parts, the mapping that 
becomes func.__globals__ must be an actual dict:
py> class Mapping:
... def __getitem__(self, key):
... if key == 'y':
... return 42
... raise KeyError(key)
...
py> from types import FunctionType
py> f = lambda x: x + y
py> g = FunctionType(f.__code__, Mapping(), 'g')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: function() argument 2 must be dict, not Mapping
I propose to allow function.__globals__ to accept any mapping type.
That, plus the new collections.ChainMap class in Python 3.3, would allow some 
interesting experiments with namespaces and scoping rules.
E.g. if I want to write a function with a custom namespace, I have to do 
something like this:
ns = ChainMap( ... ) # set up a namespace
def func(a, ns=ns):
 x = a + ns['b']
 y = ns['some_func'](ns['c'])
 z = ns['another_func'](x, y)
 ns['d'] = (x, y, z)
 return ns['one_last_thing'](d)
which is not a very natural way of writing code. But if we could use non-dict 
mappings as __globals__, I could write that function like this:
ns = ChainMap( ... ) # set up a namespace
def func(a):
 global d
 x = a + b
 y = some_func(c)
 z = another_func(x, y)
 d = (x, y, z)
 return one_last_thing(d)
# This could be a decorator.
func = FunctionType(func.__code__, ns, func.__name__)
(By the way, ChainMap is only one possible example namespace.)
-- 
Steven


More information about the Python-ideas mailing list

AltStyle によって変換されたページ (->オリジナル) /