35

Python Console with Python 3.4.2

I defined a function in a module which runs correctly in Python Console in PyCharm Community Edition 4.5.4:
ReloadTest.py:

def reloadtest(x):
    print("Version A: {}".format(x))

Python Console:

Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)] on win32
>>> from ReloadTest import reloadtest
>>> reloadtest(1)
Version A: 1   

After I modified the function to "Version B", PyCharm can't find the change, and importlib.reload(ReloadTest) gives me error.
I must reload the Python Console or restart PyCharm every time I modify a module. What did I do wrong? What is the best way to handle this?

ReloadTest.py:

def reloadtest(x):
    print("Version B: {}".format(x))

Python Console:

>>> reloadtest(1)
Version A: 1
>>> from ReloadTest import reloadtest
>>> reloadtest(1)
Version A: 1
>>> import importlib
>>> importlib.reload(ReloadTest)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'ReloadTest' is not defined
>>> from ReloadTest import reloadtest
>>> reloadtest(1)
Version A: 1
>>> import ReloadTest
>>> reloadtest(1)
Version A: 1
hxin
  • 938
  • 2
  • 12
  • 25
  • Use IPython and its [autoreload](https://ipython.org/ipython-doc/3/config/extensions/autoreload.html) function. :) – John Red Mar 02 '18 at 02:48

4 Answers4

39

You can instruct Pycharm to automatically reload modules upon changing by adding the following lines to settings->Build,Excecution,Deployment->Console->Python Console in the Starting Script:

%load_ext autoreload
%autoreload 2

enter image description here

Update: This function requires IPython (pip install ipython) as described here: Reloading submodules in IPython

Morris Franken
  • 2,435
  • 3
  • 19
  • 13
33

I took me some time to understand the previous answer... And also, that answer is not very practical if the chuck of code you need to run is in the middle of a script that you do not feel like modifying for running it once.

You can simply do:

import importlib
importlib.reload(my_module)
from my_module import my_function

Then, you can run your code with the updated version of the function.

Works with PyCharm Community Edition 2016.3.2

Edit w.r.t. first comment: This only works if you first imported the module itself (otherwise you get an error as said in the first comment).

import my_module
from my_module import my_function
# Now calls a first version of the function
# Then you change the function
import importlib
importlib.reload(my_module)
from my_module import my_function
# Now calls the new version of the function
Eskapp
  • 3,419
  • 2
  • 22
  • 39
  • 1
    Your answer is exactly the same as what my original question says, which causes a NameError and it doesn't work. Now I tried with PyCharm Community Edition 2016.3.3 again, it is still exactly like it was before. I am wondering what makes mine different from yours. – hxin May 31 '17 at 15:13
  • @armlet Indeed, I forgot to mention that this only works if you first import the module so its name is defined. I edited my answer :) – Eskapp May 31 '17 at 15:32
  • 1
    In the light of my better knowledge of Python now, your first answer is similar to mine, however at that time, it took me some time to actually make it work. So, I'll leave this answer here for new users like I was who may get confused about how to do if their modified function is called at many places in their code, and if they made their call with the function names directly. – Eskapp May 31 '17 at 15:41
12

Get it to work!
Instead of from Module import function, I should import the whole module import Module, then call the function by Module.function(). This is because

from ReloadTest import reloadtest

and

importlib.reload(ReloadTest)

can't go together.

>>> import ReloadTest
>>> ReloadTest.reloadtest(1)
Version A: 1

After making changes:

>>> importlib.reload(ReloadTest)
<module 'ReloadTest' from 'C:\\...\\ReloadTest.py'>
>>> ReloadTest.reloadtest(2)
Version B: 2
hxin
  • 938
  • 2
  • 12
  • 25
  • 1
    I got confused by all the "reload" as a function and "reload" in the module name but for whoever is also confused, you should import the reload function from importlib first, then do reload(your_module_name) – Stack_Protégé Apr 15 '21 at 15:50
5

Since this question asked specifically about PyCharm, please check out the answer on the PyCharm Support site. This answer is almost identical to @wokbot's, the distinction is that PyCharm removes the need to import importlib. It also uses the from ... import ... trick after import ... to make typing easier if you plan to use reloadtest frequently.

In[2]: import ReloadTest
In[3]: from ReloadTest import reloadtest
In[4]: reloadtest(1)
Out[4]: Version A: 1

...make changes

In[5]: reload(ReloadTest)
Out[5]: <module 'ReloadTest' from 'C:\\...\\ReloadTest.py'>
In[6]: from ReloadTest import reloadtest
In[7] reloadtest(2)
Out[7]Version B: 2
Ben
  • 1,620
  • 18
  • 11
  • 4
    With IPython you can use [autoreload](https://ipython.org/ipython-doc/3/config/extensions/autoreload.html), e.g. `%load_ext autoreload` and `%autoreload 2` – vczm Jan 30 '19 at 10:36
  • 1
    @vczm: Since you can use the IPython console in PyCharm, your comment would be the perfect answer to the question. Please consider to write an answer with it. – NemesisMF Dec 19 '19 at 09:20