Why do people always call reload right after importing their module?

I always see people when writing tools in Maya call the reload function right after importing their module like so:

import my_cool_module
reload(my_cool_module)

Why though? Isn’t it a waste of resources to reload something you just loaded? And if it’s already imported then instead of letting Python handle that by not importing it again, you explicitly force it to reload. Again, always forcing it to reload, every time a user just wants to launch your tool from a shelf button. I consistently see it in shelf buttons and tools downloaded on the internet.

I can see it being useful when you are developing and interacting with the code live. But after that, shouldn’t you remove the call to reload? I was always wondering if there is a better, legitimate reason for reloading? I don’t ship tools with a call to reload and so far I haven’t run into any issues.

I only see this in the realm of tools for animation, I don’t really see much other python code calling reload like this so often

Yes it’s inefficient, and should only be reserved for a development environment and removed for production use.

It’s just many people don’t necessarily mind the loss of performance, and other issues it may cause, so it tends to creep in to a lot of codebases.

Generally I put the reloads in while I work and just never commit those lines. So my reloads never make it into production.

Maybe stating the obvious, but because we’re using the embedded python for these tools, it isn’t easy to restart just python to force a clean load of the module.

I was at Siggraph 3(?) years ago, and there were programmers talking about how they recompiled python for some internal tools (maybe even mayapy? I don’t remember) and explicitly removed reload from the language. I’ve never dealt with anything that extreme, but reload definitely wouldn’t make it through any of our code reviews.

Ok, its like I suspected then. Thanks for the input!

It can also cause variables to break as their parent class will become a new object meaning isinstance will fail to recognise an instance from pre - reload.

To try and avoid issues with forgetting the reload and it being called when a module is imported, I put my reload statements in an

if __name__ == "main":
    reload(module)

block at the top, below the import statements

Obviously that only works if the file is imported like normal, and not run from the command line.
The ideal is to remember to remove the reloads or to auto comment them on submit.

Python 3 solves this question by making you do extra work to reload: python - Reloading module giving NameError: name 'reload' is not defined - Stack Overflow

It’s a big hint from Guido that compulsive use of reload() is a bad practice :slight_smile:

1 Like

If it’s a bad practice, what is a good practice? Sometimes those reloads are desired (for example to avoid restarting maya when syncing script updates).
I wondered if there’s a good convention such as having a function called “reload_modules()” that you can put all your reloads in. And then call it externally… but doing it that way always seems to trip me up.

Is there a way to clear the python cache so that when calling import, it treats it like a first time import?

if you have charcoal editor installed it comes with a function to revert the module state
otherwise its up to you to clean out the modules yourself, specifically the ones you want to work with

you can do this easily with the sys.modules function as the imported elements are stored there:

import sys

for modulename in list(sys.modules):
    if modulename.startswith("insertmymodulename"):
        del(sys.modules[modulename])

// from here you can import your tools and functions
from insertmymodulename.tools import myfunction

1 Like

@psykojello the main reason not to do the reload bit is the danger of dangling state: If you reload selectively and you’re not extremely clear about the side-effects of your load routine you can end up with bugs in your reloaded code which don’t exist in a pure run.

For example, you may have had a bug last time which generated some bad data in memory in a field inside some module you’re not reloading. You fix the problem by adding a check to prevent making the bad data – but it’s still sitting there, un-reloaded in a module field or something. You’ve fixed the bug for the future but it is still there in the present, convincing you to try something else. Alternately you can have the inverse: your reloaded code contains a buggy initialization routine which doesn’t run because there’s leftover state in some other module or variable that is present and correct – now your test looks great but only because of you have not exercised the code path much.

Generally reload is fine as long as you are dealing with module-level functions that don’t leave a lot of state lying around… that’s usually a nicer way to live in any case, too many class objects with too much state data multiplies the number of places where things can go wrong.