The trouble with import

One of the questions that regularly pops up is why the import statement isn't working as expected. The problem here is that you have to know what to expect. Blender has augmented the standard import behavior of Python to make it possible to import from the text files residing within a .blend file. This is a great boon because it allows you to modularize your code without the need to distribute separate files. However, the behavior of the part that imports these internal files should be absolutely clear to spare you nasty surprises but it is, at the moment, not very well-documented.

This is what happens when an import statement such as import foo is executed:

  1. Check whether foo.pyc or foo.py exists in any of the directories in sys.path
  2. If one of them exists:
    • if foo.py is newer
  3. compile foo.py to foo.pyc
    • use foo.pyc
  4. Else, if foo.py exists as an internal text file:
    • if it is not compiled already:
  5. compile internal text file
    • use compiled version
  6. Else
    • raise an exception

The first part is Python's regular behavior (it is a bit simplified from what really happens as we don't mention packages or .pyo files here) and the second part is what Blender adds to it if the required module does not exist as an external file. There are two important things to note here: if an external file exists with the same name as an internal file, the external file (or its compiled version) takes precedence. This can be annoying because many people save an external copy of an internal file with the same name. If these two are out of sync unexpected things may happen. Fortunately, Blender's internal editor reminds you of this situation by showing an Out of Sync button next to the name of the internal file. Still, if you haven't opened the text editor on that specific file, you may not notice it.

Furthermore, if you take a close look at the previous outline you will notice that if Blender is looking for an internal file it checks if this internal file is already compiled but does not check if the source might be newer. This means that any changes in the source code of an internal file that are to be imported will not be seen by the main program. To remedy this situation, you may force Python to compile the module by using the built-in reload() function. This is less efficient when running a program, but it saves a lot of headaches when developing. Once your script is production-ready you might drop the reload().

So suppose you have two internal files, main.py and mymodule.py, and you want to make sure changes in module.py, will always be visible once main.py is executed, then each file might look like this:

# main.py
import mymodule
reload(mymodule)

mymodule.myfunction()
# mymodule.py
def myfunction():
print "myfunction called"

The highlighted line shows the all important reload().

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.199.112