Reason for globals () in Python?

What is the reason for using the globals () function in Python? It only returns a dictionary of global variables that are already global, so they can be used anywhere ... I ask only out of curiosity, trying to learn python.

def F(): global x x = 1 def G(): print(globals()["x"]) #will return value of global 'x', which is 1 def H(): print(x) #will also return value of global 'x', which, also, is 1 F() G() H() 

Actually, I don’t see the point here? Only the time I needed was if I had local and global variables with the same name for both of them

 def F(): global x x = 1 def G(): x = 5 print(x) #5 print(globals()["x"]) #1 F() G() 

But you should never run into the problem of having two variables with the same name and should use them as part of the same scope.

+50
python global-variables global
Oct 02 '12 at 15:39
source share
5 answers

Python provides the programmer with a large number of tools for learning the work environment. globals() is just one of them, and can be very useful in a debugging session to see which objects the global scope actually contains.

The rationale for this, I'm sure, is the same as using locals() to view the variables defined in a function, or using dir to view the contents of a module or the attributes of an object.

Based on the background of C ++, I can understand that these things seem unnecessary. In a statically connected, statically typed environment, they would absolutely be. In this case, during compilation, it is known which variables are global, and which elements will have objects, and even which names are exported by another compilation unit.

However, in a dynamic language these things are not fixed; they may vary depending on how the code is imported or even at runtime. For this reason, at least access to this information in the debugger can be invaluable.

+69
Oct 02
source share

This is also useful when you need to call a function using the function string name. For example:

 def foo(): pass function_name_as_string = 'foo' globals()[function_name_as_string]() # foo(). 
+30
Sep 23 '13 at 17:46
source share

You can pass the result of globals() and locals() to the eval , execfile and __import__ execfile . This creates a limited environment for these teams to work.

Thus, these functions exist to support other functions that benefit from providing an environment that is potentially different from the current context. For example, you can call globals() and then delete or add some variables before calling one of these functions.

+7
Oct 02 '12 at 16:11
source share

globals() is useful for eval() - if you want to evaluate some code that refers to variables in scope, these variables will be either global or local.




To expand the bit, the built-in function eval() will interpret the line of Python code provided to it. Signature: eval(codeString, globals, locals) and you will use it like this:

 def foo(): x = 2 y = eval("x + 1", globals(), locals()) print("y=" + y) # should be 3 

This works because the interpreter gets the x value from the locals() dict variables. You can, of course, provide your own parameter variable for evaluation.

+5
Oct 02
source share

This can be useful in declarative python. For example, below, FooDef and BarDef are the classes used to define a series of data structures that are then used by some package as its input or its configuration. This allows you a lot of flexibility in what is your input, and you do not need to write a parser.

 # FooDef, BarDef are classes Foo_one = FooDef("This one", opt1 = False, valence = 3 ) Foo_two = FooDef("The other one", valence = 6, parent = Foo_one ) namelist = [] for i in range(6): namelist.append("nm%03d"%i) Foo_other = FooDef("a third one", string_list = namelist ) Bar_thing = BarDef( (Foo_one, Foo_two), method = 'depth-first') 

Note that this configuration file uses a loop to create a list of names that are part of the Foo_other configuration. So, this configuration language comes with a very powerful “preprocessor” with an available runtime library. If you want to, say, find a complex log or extract things from a zip file and base64, decode them as part of generating your configuration (this approach is not recommended, of course, for cases where the input may be from an unreliable source ...)

The package reads the configuration using something like the following:

 conf_globals = {} # make a namespace # Give the config file the classes it needs conf_globals['FooDef']= mypkgconfig.FooDef # both of these are based ... conf_globals['BarDef']= mypkgconfig.BarDef # ... on .DefBase fname = "user.conf" try: exec open(fname) in conf_globals except Exception: ...as needed... # now find all the definitions in there # (I'm assuming the names they are defined with are # significant to interpreting the data; so they # are stored under those keys here). defs = {} for nm,val in conf_globals.items(): if isinstance(val,mypkgconfig.DefBase): defs[nm] = val 

So, finally, to the point, globals() is useful when using such a package if you want to carefully measure a number of definitions:

 for idx in range(20): varname = "Foo_%02d" % i globals()[varname]= FooDef("one of several", id_code = i+1, scale_ratio = 2**i) 

It is equivalent to writing

 Foo_00 = FooDef("one of several", id_code = 1, scale_ratio=1) Foo_01 = FooDef("one of several", id_code = 2, scale_ratio=2) Foo_02 = FooDef("one of several", id_code = 3, scale_ratio=4) ... 17 more ... 

An example of a package that gets its input by collecting a bunch of definitions from a python module is PLY (Python-lex-yacc) http://www.dabeaz.com/ply/ - in this case, the objects are mostly function objects, but the metadata from function objects (their names, docs, and order of definition) are also part of the input. This is not such a good example of using globals() . In addition, it is imported using the "configuration" - the latter is a regular python script, and not vice versa.

I used "declarative python" in several of the projects I was working on, and was able to use globals() when writing configurations for them. You, of course, could argue that this was due to a lack of a way to develop a "language" configuration. Using globals() in this way does not give very clear results; simply results that might be easier to maintain than writing dozens of nearly identical statements.

You can also use it to provide the values ​​of the variables in the configuration file according to their names:

 # All variables above here starting with Foo_k_ are collected # in Bar_klist # foo_k = [ v for k,v in globals().items() if k.startswith('Foo_k_')] Bar_klist = BarDef( foo_k , method = "kset") 

This method can be useful for any python module that defines a lot of tables and structures to make it easier to add elements to data without having to maintain links.

0
Jun 20 '15 at 23:34
source share



All Articles