
{"id":4978,"date":"2024-07-12T18:33:03","date_gmt":"2024-07-12T22:33:03","guid":{"rendered":"https:\/\/ikriv.com\/blog\/?p=4978"},"modified":"2024-07-12T18:35:50","modified_gmt":"2024-07-12T22:35:50","slug":"python-eval-difference-between-globals-and-locals","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=4978","title":{"rendered":"Python eval: difference between globals and locals"},"content":{"rendered":"<p>Python <code><a href=\"https:\/\/docs.python.org\/3\/library\/functions.html#eval\">eval()<\/a><\/code> receives two optional dictionaries: <code>globals<\/code> and <code>locals<\/code>. I was finally able to find at least two differences between them.<\/p>\n<p>First difference: global variables survive until after the <code>eval()<\/code> call, local variables do not. This becomes important, if <code>eval()<\/code> returns a lambda.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nglobs = {&quot;a&quot;: 42 }\r\nlocs = {&quot;b&quot;: 10 }\r\nprint(eval(&quot;a+b&quot;, globs, locs))       # prints 52; no visible difference between usage of a and b\r\n\r\nf = eval(&quot;lambda: a&quot;, globs, locs)    # global variable &#039;a&#039; survives the eval call and can be used in a lambda later\r\nprint(f())                            # prints 42\r\n\r\nglobs&#x5B;&quot;a&quot;] = 100                      # we can even change the value of a, and the lambda will pick it up\r\nprint(f())                            # prints 100\r\n\r\ndel globs&#x5B;&quot;a&quot;]                        # if we delete globs&#x5B;&quot;a&quot;] the lambda will stop working\r\nprint(f())                            # raises NameError: name &#039;a&#039; is not defined\r\n\r\ng = eval(&quot;lambda: b&quot;, globs, locs)    # this succeeds, but local variable &#039;b&#039; will not survive beyond the eval call\r\nprint(g())                            # raises NameError: name &#039;b&#039; is not defined \r\n<\/pre>\n<p>Second difference: local variables override global variables with the same name. This, however, is applicable only during the <code>eval()<\/code> call. If <code>eval()<\/code>\u00a0returns a lambda, the global variable will be used when the lambda is invoked.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nglobs = {&quot;a&quot;: 42 }\r\nlocs = {&quot;a&quot;: 10 }\r\ndata = eval(&quot;(a, lambda: a)&quot;, globs, locs) # returns a tuple of a value and a lambda\r\nprint(data&#x5B;0], data&#x5B;1]())                  # prints &quot;10 42&quot;; lambda returns the value of the global variable\r\n<\/pre>\n<p>I could not find information about any other differences in the documentation or elsewhere on the Internet, and even those above I found through experiment. So, I am documenting them here for posterity.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Python eval() receives two optional dictionaries: globals and locals. I was finally able to find at least two differences between them. First difference: global variables survive until after the eval() <a href=\"https:\/\/ikriv.com\/blog\/?p=4978\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[4],"tags":[],"class_list":["entry","author-ikriv","post-4978","post","type-post","status-publish","format-standard","category-hack"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4978","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4978"}],"version-history":[{"count":8,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4978\/revisions"}],"predecessor-version":[{"id":4986,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4978\/revisions\/4986"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4978"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4978"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4978"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}