On Wed, Sep 2, 2020 at 8:44 AM Andras Tantos <python-l...@andras.tantosonline.com> wrote: > > While I'm sure you're right, it certainly is well hidden: > > Python 3.8.2 | packaged by conda-forge | (default, Apr 24 2020, > 07:34:03) [MSC v.1916 64 bit (AMD64)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> locals() > {'__name__': '__main__', '__doc__': None, '__package__': None, > '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': > None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>} > >>> a =3 > >>> locals() > {'__name__': '__main__', '__doc__': None, '__package__': None, > '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': > None, '__annotations__': {}, '__builtins__': <module 'builtins' > (built-in)>, 'a': 3} > >>> locals()['a'] = 4 > >>> locals() > {'__name__': '__main__', '__doc__': None, '__package__': None, > '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': > None, '__annotations__': {}, '__builtins__': <module 'builtins' > (built-in)>, 'a': 4} > >>> > > In other words, I can indeed change the value of a local variable > through the locals() dict.
Not quite. What you're seeing there is that there aren't any locals, and you're getting the globals: >>> locals() is globals() True In this situation, locals() DOES return a real dictionary, and it can be manipulated as one. But only because it's the same as globals(), and you can do all that with globals. > I've modified my code to see if I can at > least introduce locals through the value passed in for exec, but even > that seems to fail: > > classMySymbolTable(dict): > defset_type(self,t): > self.type = t > def__getitem__(self,key): > print(f"Requesting key {key} from {self.type} table") > returnsuper().__getitem__(key) > def__setitem__(self,key,value): > print(f"Setting key {key} from {self.type} table to value {value}") > returnsuper().__setitem__(key, value) > defmylocals(func): > defwrapper(*args,**kwargs): > loc = MySymbolTable() > glob = MySymbolTable(globals()) > loc.set_type("local") > loc["xxx"]=123 > glob.set_type("global") > glob["yyy"]=42 > exec(func.__code__, glob, loc) > return wrapper Your whitespace is getting messed up again, although not as badly now. Try posting in plain text, not "rich text" or HTML or formatted text or anything. > It still appears to me that 'exec()' simply ignores the dict passed in > as the local parameter: it doesn't even seem to initialize locals() from it. I'm honestly not sure what's going on, because it's hard to follow your code. But my suspicion is that when you exec a code object (rather than compiling and executing a string), it's using cells/slots rather than actually using your locals dict. ChrisA -- https://mail.python.org/mailman/listinfo/python-list