-1

I'm trying to import a function from another module; however, I can't use import because the module's name needs looking up in a list.

If I try to call the imported function ExampleFunc normally I get:

NameError: global name 'ExampleFunc' is not defined

However; if I explicitly tell python to look in locals, it finds it.


File module.py

def ExampleFunc(x):
    print x

File code.py

def imprt_frm(num,nam,scope):
    for key, value in __import__(num,scope).__dict__.items():
        if key==nam:
            scope[key]=value

def imprt_nam(nam,scope):
    imprt_frm("module",nam,scope)

def MainFunc(ary):
    imprt_nam("ExampleFunc",locals())

    #return ExampleFunc(ary)            #fails
    return locals()["ExampleFunc"](ary) #works

MainFunc("some input")
unDeadHerbs
  • 1,306
  • 1
  • 11
  • 19
  • possible duplicate of [locals().update(dictionary) doesn't add all the variables](http://stackoverflow.com/questions/24197720/locals-updatedictionary-doesnt-add-all-the-variables) – bereal Jan 27 '15 at 18:49

1 Answers1

2

The locals() dictionary is but a reflection of the actual locals array. You cannot add new names to the locals through it, nor can you alter existing locals.

It is a dictionary created on demand from the actual frame locals, and is one-way only. From the locals() function documentation:

Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.

Function locals are highly optimised and determined at compile time, Python builds on not being able to alter the known locals dynamically at runtime.

Rather than try and stuff into locals directly, you can return the one object from the dynamic import. Use the importlib module rather than __import__ here:

import importlib

def import_frm(module_name, name):
    module = importlib.import_module(module_name)
    return getattr(module, name)

then just assign to a local name:

def MainFunc(ary):
    ExampleFunc = import_from('module' , 'ExampleFunc')
    ExampleFunc(ary)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • then why when I add something to globals() in the same way does it work? – unDeadHerbs Jan 27 '15 at 18:47
  • @undeadherbs: because `globals()` is not such a reflection. Locals is highly optimised for the frame. – Martijn Pieters Jan 27 '15 at 18:49
  • @undeadherbs what's local and what's not is defined during the function compilation. Allowing changing that dynamically would prevent the optimization and allow for some other surprises. – bereal Jan 27 '15 at 18:51