Forum Archive

Sub modules not updated automatically

marcus67

In my app distributed over several module files I have come cross a strange behavior. It seems to me as though sub modules which are used by main modules are not updated automatically. Instead the old public interface remains visible to the main modules until the Pythonista app is closed and reopened. Is there a way to avoid this since this is a little annoying? I often start looking for declaration errors which are due to the outdated sub modules.

The quickest way to reproduce this behavior is using modules "a" and "b":

module a:


def a():
  return "a"

module b:


import a

print a.a()

Start b for the first time. It will work and print "a". Then change modules "a" and "b" to:

module "a"


def a1():
  return "a"

module b:


import a

print a.a1()

Start module "b" again. It will say that the name "a1" is not known. Then close the app, reopen and restart module "b".

ccc

Call reload() on modules that have changed. You can search the forum for 'reload' for other discussions of this issue.

omz

In version 1.5, you need to use the reload() function manually, as suggested by @ccc. This shouldn't be necessary anymore in the next version.

marcus67

Unfortunately, reload() does not seem to work with "from import *" which I'm using a lot to keep identifiers short.

dgelessus

If you use from-imports, then you need to reload the scripts in order and/or more than once, because you're assigning module attributes to new names that are no longer linked to the source module. If you access attributes over the module instead of from-importing them, they are always looked up through the module object, which always has the up-to-date references.

In many cases it's a bad idea to use from module import * at all, as it can cause a few obscure bugs. (For example from os import * shadows the built-in open function, meaning that you cannot open files easily anymore. Your program might also break in the future if a module is updated and gets new attributes, which are automatically star-imported into your module.) A few packages, usually large libraries and frameworks like tkinter, are specifically designed to be star-import-safe and are often used that way.

If you only use one or two things from a module, a from import can be useful to show that, but if you use a module a lot then a normal import is cleaner, because you don't need to remember which global comes from which module. (This is another reason why star-imports are problematic - it's impossible to see where a global comes from without checking every imported module.)

ccc

This syntax will work:

import my_module
reload(my_module)
from my_module import my_function
ccc
  • https://www.python.org/dev/peps/pep-0008/#imports
  • https://docs.python.org/2/tutorial/modules.html#more-on-modules
  • https://docs.python.org/2/tutorial/modules.html#importing-from-a-package

Talk about why wildcard imports (from import *) are frowned upon.

marcus67

I did not know that I could use both import variants at the same time. I will definitely try that. Also I will try to eliminate the "from m import *" variants wherever possible.
Thanks for your advice!

ccc

Python v2.7.11 release candidate 1 was just released and one of the documentation issues fixed was: Issue #20769: Improve reload() docs. Patch by Dorian Pula.

marcus67

Changing all the imports as @ccc had suggested took care of the problem. Syntax errors are always "real" errors now. :-) Thanks a lot!