Pycharm interactive console does not work

19,142

Solution 1

It depends on how you 'run' the python file. There are plenty of ways to do that from within pycharm (perhaps too many).

I'm guessing what you're doing is pressing the green triangle. This doesn't execute the file in the same shell that exists in the "Python Console" tab at the bottom. It instead spawns a new shell, executes the file, and by default closes the shell when the file is done executing. You can see this shell do it's thing in the 'Run' tab at the bottom. It would seem from Shivendra's reply that there may be a way to avoid killing the shell on script exit. If this is indeed the case, you would be using a terminal / shell that remains in the 'Run' tab and not the one in the 'Python Console' tab.

This is very similar to what happens if you use Debug instead of Run. It spawns an interpreter, attaches the debugger, runs the script, kills everything when it's done. This lives in the 'Debug' tab.

The simplest way to achieve what you have in mind would be to run the file within the pre-existing 'Python Console', as follows. In this case, the script is run as if it were __main__, so if you have an if __name__ == "__main__":, it would evaluate to True and any code within the if block will be executed as well. (More on this later, if you don't know what it is right now)

In[2]: dir()
Out[2]: 
['In',
 'Out',
 '_',
 '__',
 '___',
 '__builtin__',
 '__builtins__',
 '__doc__',
 '__name__',
 '__package__',
 '_dh',
 '_i',
 '_i1',
 '_i2',
 '_ih',
 '_ii',
 '_iii',
 '_oh',
 '_sh',
 'exit',
 'get_ipython',
 'quit',
 'sys']
In[3]: run -m conventions.iec60063
In[4]: dir()
Out[4]: 
['Decimal',
 'E12',
 'E24',
 'E3',
 'E6',
 'In',
 'Out',
 '_',
 '_3',
 '__',
 '___',
 '__builtin__',
 '__builtins__',
 '__doc__',
 '__loader__',
 '__name__',
 '__nonzero__',
 '__package__',
 '_dh',
 '_i',
 '_i1',
 '_i2',
 '_i3',
 '_i4',
 '_ih',
 '_ii',
 '_iii',
 '_oh',
 '_sh',
 'cap_ostrs',
 'elem',
 'exit',
 'gen_vals',
 'get_ipython',
 'get_series',
 'idx',
 'ind_ostrs',
 'quit',
 'res_ostrs',
 'sys',
 'zen_ostrs']

My preferred way to 'run' a file is to just import it from within the 'Python Shell' (IPython or otherwise) itself and manually run whatever initialization code needs to be run. This has the advantage not overly polluting the namespace and presenting an environment which is much closer to what you'd expect if you were using the script as a module (which is where pycharm and IPython and auto-completion really start paying off). In both methods, you have the option of attaching the debugger to 'Python Console's interpreter using the 'Attach Debugger' icon next to the shell (the green bug).

A short example is as follows (in the 'Python Console' tab):

In[2]: dir()
Out[2]: 
['In',
 'Out',
 '_',
 '__',
 '___',
 '__builtin__',
 '__builtins__',
 '__doc__',
 '__name__',
 '__package__',
 '_dh',
 '_i',
 '_i1',
 '_i2',
 '_ih',
 '_ii',
 '_iii',
 '_oh',
 '_sh',
 'exit',
 'get_ipython',
 'quit',
 'sys']
In[3]: import conventions.iec60063
In[4]: dir()
Out[4]: 
['In',
 'Out',
 ... (all the same ones as before)
 'conventions',
 ... (all the same ones as before)
]

In essence, you wouldn't be running the file as such, though, so you should be aware of what you're doing.

When you execute a python file, the module thinks it's __name__ is "__main__", and this is the origin of the if __name__ == "__main__": trick (which is something you should definitely look up early on in the python learning process). If you then try to follow execution of the code, the interpreter executes everything in the module that isn't a class or a function or so. This includes the if __name__ == "__main__": condition you'll see in many python scripts. The contents of the if block, are only executed if the script is run by itself (or using run -m module in IPython)

On the other hand, when you import a module, the same execution sequence happens, except for the fact that if __name__ == "__main__": will evaluate to False and any code residing in that block won't be called. You should therefore manually execute whatever is in the if __name__ == "__main__": block if you need it. One common pattern to simplify that task is to just have a minimal function call within the if block (or, if you care about command line arguments, just handle those there), which then hands off the bulk of the execution to an easily callable function:

def main():
    pass

if __name__ == "__main__":
    main()

In case you then end up importing the module but need to execute that code anyway, all you need to do is call the main() function. In the example above, what I'd do (if I had to execute some code when the module 'runs') would look something like :

In[2]: import conventions.iec60063
In[3]: conventions.iec60063.main()

Pycharm has some other more exotic ways of executing code (for executing only a small fragment of a file and such), which I've not really needed so I don't quite know how they'd work.

Solution 2

For retaining objects/ classes/ functions/ variables even after execution you will have to change the Interpreter Option in Run> Edit Configuration> Interpreter Option, you have to add -i there. I still don't know about code completion in the console.

Share:
19,142
Jason
Author by

Jason

Updated on June 08, 2022

Comments

  • Jason
    Jason about 2 years

    I am new to both python and Pycharm. Thus, please do not hesitate to point out where I did wrong and how I can fix the problem.

    The problem is that IPython can not import the functions I want to execute as usual. Even after the python file runs, I cannot import the functions from that file in IPython console. Besides there is no code completion in IPython console.

    For example, I write a python file named student.py, in which I define a class named student. Then I run this file. But IPython console says class 'student' is not defined, when I type student('Jack', 28) in console.

    class student(object):
        def _init_(self, name, age):
            self.name=name
            self.age=age
    

    What makes me confused is that I can run the file. But when I type student('Jack', 28) in console, IPython console says

    Traceback (most recent call last):
    File "/Library/Python/2.7/site-packages/IPython/core/interactiveshell.py", line 3032, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
    File "<ipython-input-2-483e7a488507>", line 1, in <module>
    student('Jack',28)
    NameError: name 'student' is not defined
    

    What's more, IPython Magic Function also does not work in IPython console.

    In[3]: %run student.py
    ERROR: File `u'student.py'` not found.
    

    Sorry for no pictures to make the situations more clear because of not enough reputations.

  • Jason
    Jason about 9 years
    Thanks, I opened Run> Edit Configuration> Interpreter Option, but I didn't know where to add -i. Could you please explain that more explicitly?
  • Jason
    Jason about 9 years
    I found Interpreter Option and type -i student.py. But it doesn't work.
  • Shivendra
    Shivendra about 9 years
    type only -i and then apply it and run your code as usual
  • Jason
    Jason about 9 years
    The problem is that type neither run -m student nor import student did not work. IPython said u'student' is not a valid modulename on sys.path for run -m method and No module named student for import method
  • Chintalagiri Shashank
    Chintalagiri Shashank about 9 years
    Check in settings > Build, Execution, Deployment > Console > Python Console. You should have something like sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS] in the starting script. I use the default (I expect - don't remember changing it) of add content root to PYTHONPATH selected, and in order to be able to import student or run -m student or what have you, student.py should exist in your root folder or a package (folder with init.py) called student should exist in project root.
  • Chintalagiri Shashank
    Chintalagiri Shashank about 9 years
    If student is in a subfolder, you'll have to import it with it's relative path from the project root. If your file structure is <projectname>/somedirectory/student.py, you should be using import somedirectory.student as student or run -m somedirectory.student. I expect somedirectory will have to be a package as well, ie, must have an __init__py file (empty one will do)
  • Jason
    Jason about 9 years
    Thanks for yr suggestions. I fixed the run -m problem. That may result from that there is folder named in Chinese in the path of student.py. However, after run -m student.py successfully, I type student('Amy', 12), IPython console said object() takes no parameters. While I can run the file in ipython qt-console.
  • Chintalagiri Shashank
    Chintalagiri Shashank about 9 years
    Check your code and the namespaces. Most likely you're using the namespaces inconsistently somewhere.
  • Cina
    Cina over 7 years
    thanks. this is exactly I needed. One question, what actually does "-i" option? and does it effect the performance of interpreter?
  • Shivendra
    Shivendra over 7 years
    It stands for interactive mode. It's a python command line feature and not pycharm's, so it will work on any console/terminal.
  • Shivendra
    Shivendra over 7 years
    It won't affect the performance. And I suggest you use the ipython console in pycharm rather than python with -i option.