How to use "from modname import *" to create and modify global names?
Question: I have read [the
documentation](https://docs.python.org/3.3/reference/simple_stmts.html#the-
import-statement) and also [this comprehensive
answer](http://stackoverflow.com/questions/710551/import-module-or-from-
module-import) but something doesn't work as I expect. I hoped to use `from
set_stuff_up import *` as basically an "include" statement to define some
boilerplate globals and functions, but something doesn't work as I'd expect.
Here is set_stuff_up.py:

    
    
    public_name = None
    def set_public_name():
        global public_name # makes no diff
        public_name = 'HELLO DERE'
    

However the following code:

    
    
    from set_stuff_up import *
    print('public_name is',public_name)
    set_public_name()
    print('public_name is',public_name)
    

produces the output:

    
    
    public_name is None
    public_name is None
    

In other words, `from set_stuff_up import *` did bind `public_name` "in the
local namespace for the scope where the import statement occurs" but somehow
the function `set_public_name` operates on a different public_name, regardless
of the global statement.

Can somebody clarify the way the namespaces are operating in this case? And is
there a way to have the imported function operate on the imported public name?


Answer: It's important to understand that Python variables are names referring to
values. The globals of a module are names that refer to values. When you use
`from set_stuff_up import *`, that means, make names in this module that refer
to the same values as the corresponding names in set_stuff_up. So now you have
two names, `set_stuff_up.public_name`, and `my_module.public_name`, both
referring to the same value (None in this case). When you run
`set_public_name`, you are reassigning `set_stuff_up.public_name` to refer to
a new value. Your other name, `my_module.public_name` is unaffected.

Names cannot refer to other names, only to values. Your situation here is no
different than:

    
    
    a = 1
    b = a
    a = 2
    

You don't expect b to equal 2 at this point. Assigning to a doesn't affect any
other name that shares the same value as a.

For more detail on this, see [Facts and Myths about Python Names and
Values](http://nedbatchelder.com/text/names.html).

There isn't a way to organize your code to get the exact effect you are
looking for. You could use this:

    
    
    import set_stuff_up
    print('public_name is', set_stuff_up.public_name)
    set_stuff_up.set_public_name()
    print('public_name is', set_stuff_up.public_name)
    

