10

As we know that, in python 2.x, if we divide two integer values it results in an int. However, if using from __future__ import division, we instead get a float value.

>>> 3/2
1
>>> from __future__ import division
>>> 3/2
1.5
>>> 
>>> 
>>> 3//2
1
>>> 4/3
1.3333333333333333
>>> 

So, // instead of / should be used if we want integers after importing __future__.division, but I want to know how to make / to return integers again.

Is there any way to un-import or remove the previously imported module?


There is a method to unimport libs or Modules in IDLE, that is to Restart it by using Ctrl+F6 or Options in Menu

Marslo
  • 2,994
  • 4
  • 26
  • 35
  • @NedBatchelder That's exactly my question. – Marslo Sep 27 '12 at 01:43
  • Please don't post the same question again, @Marslo. If you don't get good answers, try to improve your existing question by adding more detail or clarifying it. – Don Kirkby Jan 14 '13 at 20:58
  • For what it's worth, you should be using `//` anytime you want integer division. If you use `/` your code should either be robust enough to handle either integer or true division, or you should be using `__future__` so that you know for certain that you're using true division. – mgilson Nov 03 '13 at 02:19
  • even after \_\_future\_\_ "modules" are imported, there isn't a way to remove them - even with `del division; from sys import modules; del modules['__future__']`. I think this import overwrites something in the interpreter or something. However, with other standard imports, deleting (though this is risky and should almost never be done) modules can be done by `del`eting `sys.modules[MODULE_NAME]` – dylnmc Oct 25 '16 at 04:33

4 Answers4

11

python has reload to re-import an already imported module (which shouldn't be used in production code), but there is no way (that I know) to un-import a module once it's been imported.

Of course, you can just delete the reference to that module in your current namespace:

import module
module.foo()
del module
module.foo() #NameError, can't find `module`

Another point is that __future__ isn't really a module. It's more of an instruction to tell the parser how to behave. As such, when put in a file, it needs to be the first thing in there (before any other imports, etc). The fact that you can import __future__ from anywhere in an interactive session is a special case.

Community
  • 1
  • 1
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • There are ways to unimport modules, e.g. you can just `del` them. It doesn't work for `__future__`, though. – Lev Levitsky Sep 19 '12 at 15:23
  • @LevLevitsky -- No, that removes the reference to the module in the current namespace, which isn't the same thing. -- And it doesn't work if you `from module import *`. – mgilson Sep 19 '12 at 15:24
  • @LevLevitsky -- You might be able to do something with `sys.modules` to remove it, but that's questionable... – mgilson Sep 19 '12 at 15:25
  • It kinda works with `from module import *`, you just have to know what names to delete. – Lev Levitsky Sep 19 '12 at 15:31
  • @mgilson: There exists prior art for this. (I'm too lazy to look it up at the moment, sorry.) It gets complicated to do correctly, but it can be done, and made to work well in all cases. It's more correct to say "there's no *officially supported* way". IIRC the solution involves registering an import hook and figuring out some fiddly back-in-time logic to fix all the references to the module object. – bukzor Sep 19 '12 at 15:35
  • Yes! **del moudle_name** works for the condition of **import moudle_name**. I still find the way of the condition of **from xxx import xx**, I think I can find them by **print sys.modules** or **print sys.modules.keys()** – Marslo Sep 19 '12 at 16:39
5

__future__ looks like a module but isn't really. Importing it actually affects the compilation options of the current module. There's no way to "undo" it, since it effectively happens before the module is even executed.

If it were any other "normal" module, there are ways, but you're out of luck here. Either deal with the changed semantics, or put the code that needs different compilation in a separate module.

bukzor
  • 37,539
  • 11
  • 77
  • 111
  • So, undo the 'normal' module is by using 'del', isn't it? – Marslo Sep 19 '12 at 15:38
  • 1
    Marsalo: No. If you want to change your question I'll answer it, but that won't work in the general case. The module object will stil be referenced by `sys.modules` and by any modules which imported it afterward. `del sys.modules['modulename']` is closer but still incomplete. – bukzor Sep 19 '12 at 15:41
  • Well, I think 'del' works. I tested by 'Math' module, and it was unimport by ` del math ` – Marslo Sep 19 '12 at 16:10
  • But **sys.modules['math']** doesn't work!! That's strange! the 'math' module do delete from sys.modules. I print them twice, before and after by using 'sys.modules['math'] '. – Marslo Sep 19 '12 at 16:28
  • I think you're missing the fact that `import` makes the sys.modules entry: https://gist.github.com/3751495. Note that this doesn't address the issue of any other references to the module, and as such isn't fully reliable / production worthy. – bukzor Sep 19 '12 at 18:57
  • I have added my comment. I'm just strange that math module works even if `'math'` is not exists in `sys.modules` anymore. – Marslo Sep 20 '12 at 06:51
2

I also have faced this need.

I don't use __future__.

When I need a float result, I make the divisor a float:

>>> 3/float(2)
1.5
Chris
  • 6,805
  • 3
  • 35
  • 50
Yueyoum
  • 2,823
  • 5
  • 23
  • 26
-3

You can unload it using:

>>> del(module)
Helder
  • 482
  • 5
  • 18
  • 1
    yes, **del moudle_name** works at some condition, like **import moudle_name**, but it seems cannot work for **from xxx import xxx**. – Marslo Sep 19 '12 at 16:35
  • This does not unload the module. The object still exists in `sys.modules`, at a minimum. – bukzor Sep 19 '12 at 18:58