Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pycharm interactive console does not work

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.

like image 936
Jason Avatar asked Sep 29 '22 10:09

Jason


1 Answers

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.

like image 75
Chintalagiri Shashank Avatar answered Oct 06 '22 20:10

Chintalagiri Shashank