Confusion of Python __import__ parameter

I am trying to import a module by passing some global variables, but it does not work:

File test_1:

test_2 = __import__("test_2", {"testvar": 1}) 

File test_2:

 print testvar 

It seems like it should work and print 1, but when running test_1 I get the following error:

 Traceback (most recent call last): File ".../test_1.py", line 1, in <module> print testvar NameError: name 'testvar' is not defined 

What am I doing wrong?

EDIT:

As I said later, this is an attempt to replace functions in the graphics library. Here is an example of a program (which my teacher wrote) using this library:

 from graphics import * makeGraphicsWindow(800, 600) ############################################################ # this function is called once to initialize your new world def startWorld(world): world.ballX = 50 world.ballY = 300 return world ############################################################ # this function is called every frame to update your world def updateWorld(world): world.ballX = world.ballX + 3 return world ############################################################ # this function is called every frame to draw your world def drawWorld(world): fillCircle(world.ballX, world.ballY, 50, "red") ############################################################ runGraphics(startWorld, updateWorld, drawWorld) 

Please note that this code is designed in such a way that people who have never (or almost never) seen ANY code before (and not just python) could understand with minimal effort.

Example for rewriting a function:

Source:

 def drawPoint(x, y, color=GLI.foreground): GLI.screen.set_at((int(x),int(y)), lookupColor(color)) 

Code entered:

 # Where self is a window (class I created) instance. def drawPoint(x, y, color = self.foreground): self.surface.set_at((int(x), int(y)), lookupColor(color)) 

I assume that my real question is: how would I introduce global functions / variables into an imported module before starting the module ...?

+6
python import global
source share
6 answers

I ran into the same problem ... And I convinced myself with the following technique ... I do not know if this will be useful to you or not!

File2: test1.py

 global myvar myvar = "some initial value" print myvar test = __import__("test2") print myvar 

File2: test2.py

 import inspect stk = inspect.stack()[1] myvar = inspect.getmodule(frm[0]).myvar print myvar myvar = "i am changing its value." 

Here the variable is passed from module 1 to module2 and this is also passed by reference.

+3
source share

As the docs explain, the globals parameter on __import__ does not "add" additional globals to the imported module, as you seem to believe - indeed, that globals() the import module usually goes there, so such an injection would be very problematic if this happened . Indeed, __import__ docs specifically say:

The standard implementation does not generally use the argument of its local residents and uses its global values ​​only to determine the context of the packaging import statement.

Edit : if you need an injection, for example. into an empty imported module, as suggested by OP in the comment, it’s easy if you are fine by executing immediately after import:

 themod = __import__(themodname) themod.__dict__.update(thedict) 

The imported body module will not know about the continuation of the injections, but this is clear, regardless of whether the specified body is empty anyway ;-). Immediately after import, you can enter the contents of your heart, and all subsequent applications of this module will see your injections as if they were bona fide names at the module level (because they are :-).

You could even, if you want, save the need for an empty .py module to start with ...:

 import new, sys themod = new.module(themodname) sys.modules[themodname] = themod themod.__dict__.update(thedict) 

Edit : OP is trying to clarify in editing Q ...:

I think my real question is: how do I introduce global functions / variables into an imported module before the module works ...?

"The module starts" does not make much sense ", the modules are loaded (which their body executes), only once (unless re- loaded explicitly later) ... they never" start "" as such. Given an empty module, you first import it (which has not done anything since the empty module), then you can, if you want to use a combination of themodule.__dict__.update and attribute assignment to populate the module - the function is not automatically called when it is just mentioned (because The OP expresses concerns that they will be in the commentary), so they can be treated like any other variable in this regard (and most others, so Python said it has first class ).

+7
source share

As said, the __import__ function does not add global variables to the new module. If you want to do this, I would suggest adding some initialize () function that assigns the value to a previously declared global table, for example:

 gTable = {} gInited = False def initialize(table): if(not gInited): gTable = table gInited = True def getGlobal(name): if(name in gTable): return gTable[name] else: throw NameError("name '"+name+"' is not defined") def setGlobal(name, value): gTable[name] = value def mod_main(): print getGlobal("testvar") 

and import it as follows:

 import modGlobalsTest modGlobalsTest.initialize({"testvar": 1}) modGlobalsTest.mod_main() 

If you want to change the functions in the imported library, you can do something like this:

 import foobar def bar(x): return x+1 foobar.foo = bar 

to replace foobar.foo with a custom dashboard.

+2
source share

You try too hard, you just need a simple import Define a variable in one module, say test1

 testvar = 1 

in test2 put

 import test1 print test1.testvar 
0
source share

It looks like you want to embed code in a graphics library and run sample programs using this. If so, you can do it like this:

 import graphics graphics.drawPoint = myDrawPoint 

You can also write a program that takes a file name as an argument and does the following:

 import sys import graphics def main(): graphics.drawPoint = myDrawPoint execfile(sys.argv[1]) 
0
source share

when I need to pass global values ​​to a module at boot (which is pretty common), I just create a new ModuleType , insert globals, a namespace into it, and finally execute my source module in that namespace.

Here is my code for basic import of a submodule:
(for the package you will need the global variables __package__ and __path__ )

 # such a headache to initialize a module requiring globals >_< import sys,os, types.ModuleType as ModuleType globals()['nodes'] = sys.modules['nodes'] = ModuleType('nodes') # set the namespace nodes.__dict__.update(dict( __name__ = 'nodes', __file__ = __file__.replace(__name__,'nodes'), # the globals I need in particular GL = GL, # prevents a ghost (duplicate) import drawText = drawText, lenText = lenText )) with open('nodes.py','rb') as src: exec( src.read(), nodes.__dict__ ) 

I cannot just import nodes , or I will get a NameError, because lenText used when building definitions for getting into node classes in this module.

Tips: be careful where you use it!
In my case, lenText works with a link to the display list of each character, so I need to import it after preparing my GL context.

0
source share

All Articles