Re-import module?
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Re-import module?
TFT, as usual this pensioner is behind the curve At least we now have a specific piece of Cpython functionality to discuss.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
- polygontwist
- Posts: 36
- Joined: Sat Jun 28, 2014 4:54 pm
- Location: Germany, Rostock
- Contact:
reimport imported Modules (del ?)
Hello,
How can I delete an imported module to import it again?
I found the command "del",it works(?) but it does not delete the imported module.
I write .py files and would like to import again without resetting the board.
(edit: v1.3.4-1-g3e42570 on 2014-10-22)
How can I delete an imported module to import it again?
I found the command "del",it works(?) but it does not delete the imported module.
I write .py files and would like to import again without resetting the board.
(edit: v1.3.4-1-g3e42570 on 2014-10-22)
Re: Re-import module?
sys.modules is now implemented, so it's possible to trigger re-importing of a module.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Re-import module?
@pfalcon Very useful!
@polygontwist In case you didn't follow @pfalcon's post, Python caches imported modules in a dictionary called sys.modules. This caters for the case where a module gets imported more than once: if it's in the dictionary Python doesn't bother re-importing it. So, if you want to re-import module foo, with a new firmware build issue
@polygontwist In case you didn't follow @pfalcon's post, Python caches imported modules in a dictionary called sys.modules. This caters for the case where a module gets imported more than once: if it's in the dictionary Python doesn't bother re-importing it. So, if you want to re-import module foo, with a new firmware build issue
Code: Select all
import sys
del sys.modules['foo']
import foo
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Re-import module?
Basically that works and is very useful. But if the first loaded module contains and registers an ISR, this one will be called, and any signaling using a global symbol will not work, since the first loaded ISR and the secondly loaded module will stare at different places At least that's what I observed when I tried to use the approach after pfalcon announced it. And obviously, the first loaded modules still sits in memory.
-
- Posts: 463
- Joined: Wed Apr 08, 2015 5:19 am
Re: Re-import module?
Thats one reason why using module globals to keep state is usually bad programming practice and executing code on import (e.g. registering an ISR) even more so. The same problems would exist with CPython. It also can't magically update any existing object instances from the re-imported module to use the new code.Roberthh wrote:But if the first loaded module contains and registers an ISR, this one will be called, and any signaling using a global symbol will not work,
Re: Re-import module?
So wouldn't loading the module the second time - reregister the ISR, thus replacing the old definition?SpotlightKid wrote:Thats one reason why using module globals to keep state is usually bad programming practice and executing code on import (e.g. registering an ISR) even more so. The same problems would exist with CPython. It also can't magically update any existing object instances from the re-imported module to use the new code.Roberthh wrote:But if the first loaded module contains and registers an ISR, this one will be called, and any signaling using a global symbol will not work,
There is still a window where if the ISR occurs between deleting the old module and re-importing the new one where it will still point to the old routine, but as soon as the new ISR is registered, the old one should go away. There are some exceptions (like Exti) where if you were planning on using reimporting, then I would register an ISR of None, first, and then register the new ISR.
Re: Re-import module?
Actually in the example code I used the ISR was registered by a function in the loaded module, not at load time of the module, and the interrupt is caused by a one-shot timer. I may set up an example where the interrupt is triggered by an external pulse generator, where I can better control how many events occur. And thinking about SpotLightKid's comments, it could also be that it is the global which is not updated. I could try to look further. In any case, I would expect that loading a module would replace or re-use previous symbol definitions.
And, b.t.w., there was not specific reason to use that example code. It was just a short piece of code at hand that was loaded to the WiPy.
----- Update ----
Trying to simplify the test, it looks as if runs everything as expected on PyBoard. Here is the short test code:
I can delete the module from sys.modules, change the code (e.g. by choosing LED(2)), reimport it, and then the other led lights up, and the stae of 'fired' is changed too. A similar code on WiPy w/o LED behaves strange. I can load it once, it triggers the 'fired' flag. But if I quit and call the function again, the flag is never changed again, until I do a HARD reset. Thats with build 1.5.1-116. That seems to be the reason why I assumed that reloading did not work. Here's the Wipy code:
And, b.t.w., there was not specific reason to use that example code. It was just a short piece of code at hand that was loaded to the WiPy.
----- Update ----
Trying to simplify the test, it looks as if runs everything as expected on PyBoard. Here is the short test code:
Code: Select all
import sys
from pyb import Timer, LED
fired = None
def reload(time=1):
global fired
print ("Enter the magic ANYKEY or 'q' to quit")
tim = Timer(1)
tim.init(freq = time)
tim.callback(my_interrupt)
while True:
fired = False
ch = sys.stdin.read(1)
print ("{!r} {} ".format(ch, fired), end="")
if ch == "q":
tim.deinit()
print ("")
break
def my_interrupt(timer):
global fired
fired = True
LED(1).toggle()
Code: Select all
import sys
from machine import Timer
fired = None
def reload(time = 1000000):
global fired
tim = Timer(1)
tim.init(mode = Timer.ONE_SHOT, width = 32)
print ("Enter the magic ANYKEY or 'q' to quit")
while True:
tim_ch = tim.channel(Timer.A | Timer.B, period = time)
tim_ch.irq(handler = my_interrupt)
fired = False
ch = sys.stdin.read(1)
print ("{!r} {} ".format(ch, fired), end="")
if ch == "q":
tim.deinit()
print ("")
break
def my_interrupt(timer):
global fired
fired = True
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Re-import module?
For all its limitations reload can be very useful. I've put the following in boot.py (so that reload appears in Python's namespace).
It differs from the Python standard function in that the name of the module to be reloaded must be passed as a string:
Perhaps someone fancying a puzzle for the festive season can fix this?
Code: Select all
def reload(mod):
import sys
z = __import__(mod)
del z
del sys.modules[mod]
return __import__(mod)
Code: Select all
PYB: sync filesystems
PYB: soft reboot
MicroPython v1.5.1-127-g67a5bfc on 2015-12-17; PYBv1.1 with STM32F405RG
Type "help()" for more information.
>>> import cow
0
>>> reload('cow')
0
<module 'cow' from 'cow.py'>
>>>
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.