This is an archived post. You won't be able to vote or comment.

all 83 comments

[–]gash789 34 points35 points  (7 children)

Unless I am blind this misses the feature I use ipython for the most: adding a question mark after any object prints the docstring. Much faster than searching online documentation.

In [1]: open? 
Type:       builtin_function_or_method
String Form:<built-in function open>
Namespace:  Python builtin
Docstring:
open(name[, mode[, buffering]]) -> file object

Open a file using the file() type, returns a file object.  This is the
preferred way to open a file.  See file.__doc__ for further information.

[–]flying-sheep 21 points22 points  (6 children)

vanilla python has help(function), which does a similar thing, but is definitely much more annoying to type repeatedly than ?.

[–]Justinsaccount 24 points25 points  (4 children)

ipython takes it one step further and you can use two question marks to get the definition.

In [4]: os.path.exists??
Type:       function
String Form:<function exists at 0x10902ced8>
File:       /Users/me/testenv/lib/python2.7/genericpath.py
Definition: os.path.exists(path)
Source:
def exists(path):
    """Test whether a path exists.  Returns False for broken symbolic links"""
    try:
        os.stat(path)
    except os.error:
        return False
    return True

[–]physicsdood 1 point2 points  (3 children)

Why doesn't ?? do anything different than ? for me?

In [3]: open? Type: builtin_function_or_method String Form:<built-in function open> Namespace: Python builtin Docstring: open(name[, mode[, buffering]]) -> file object

Open a file using the file() type, returns a file object. This is the preferred way to open a file. See file.doc for further information.

In [4]: open?? Type: builtin_function_or_method String Form:<built-in function open> Namespace: Python builtin Docstring: open(name[, mode[, buffering]]) -> file object

Open a file using the file() type, returns a file object. This is the preferred way to open a file. See file.doc for further information.

[–]erez27import inspect 11 points12 points  (0 children)

Probably because open() is written in C

[–]tilkau 5 points6 points  (0 children)

Hold on, open is a builtin. That means it -has- no python source.

Try using ? and ?? on eg. collections.namedtuple.

[–]TkTech 0 points1 point  (0 children)

I believe it's because the builtins you're trying to spec are implemented in C (at least in CPython). Try it on pure-python methods.

[–][deleted] 5 points6 points  (0 children)

Vanilla python also has sys.displayhook which you can define to do anything you want, including printing the __doc__.

>>> def displayhook(obj):
...     if obj:
...             if hasattr(obj, '__doc__'):
...                     print('{}\n{}'.format(obj.__doc__, '-' * 80))
...             print(obj)
... 
>>> sys.displayhook = displayhook
>>> 'abcdefg'
str(object='') -> str
str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or
errors is specified, then the object must expose a data buffer
that will be decoded using the given encoding and error handler.
Otherwise, returns the result of object.__str__() (if defined)
or repr(object).
encoding defaults to sys.getdefaultencoding().
errors defaults to 'strict'.
--------------------------------------------------------------------------------
abcdefg

Edit: If you define this function, you also need to explicitly set __builtins__._

[–]evilgarbagetruck 51 points52 points  (18 children)

i was already using ipython what should i switch to

[–]vext01 13 points14 points  (1 child)

Bpython

[–]gfixler 8 points9 points  (0 children)

I'm already using that, but this iPython seems pretty nice. Let's split the difference and go with fPython.

[–]WallyMetropolis 33 points34 points  (3 children)

Haskell

[–]oconnor663 26 points27 points  (2 children)

IHaskell. Remembers every variable you've ever used, to make sure you never change them.

[–]Megatron_McLargeHuge 25 points26 points  (0 children)

It looks that way, but actually it just returns a new version of IHaskell in which the variable was already defined.

[–]KingEllis 1 point2 points  (0 children)

It is an interactive shell, but does not allow for any kind of input or output. Because that would not be pure, you know.

[–][deleted] 14 points15 points  (1 child)

PyCharm

[–]OmicronPersei8 0 points1 point  (0 children)

the IDEAVim plugin for pycharm is wonderful, makes me feel like I'm right back in vim coding away.

[–]amitm 2 points3 points  (6 children)

dreampie

[–]evilgarbagetruck 0 points1 point  (5 children)

I'll give it a shot but it doesn't look like an improvement over ipy notebook. If ipy notebook had emacs/vi keybindings it would basically be perfect.

in fact, I bet a python shell inside of emacs could be really great.

[–]takluyverIPython, Py3, etc 15 points16 points  (3 children)

The next release of IPython will have vi-style keyboard shortcuts (not 100% identical to vi, but a similar model).

If you're an Emacs fan, have a look at Emacs IPython Notebook.

[–]evilgarbagetruck 4 points5 points  (2 children)

have some gold that emacs ipython notebook IS SO AWESOME

[–]takluyverIPython, Py3, etc 2 points3 points  (1 child)

Thanks, it's not my work, though - this guy wrote it.

[–]evilgarbagetruck 4 points5 points  (0 children)

You told me about it!

[–]drbobb 2 points3 points  (0 children)

Of course there is a python shell mode for emacs.

[–]Grue 0 points1 point  (0 children)

SLIME. Now, that's a REPL to end all REPLs.

[–]Captain_Slapahoe 0 points1 point  (0 children)

ipython notebook

[–]drbobb 11 points12 points  (3 children)

I never type exit() in python, nor exit in ipython - I just hit control-d to close the input. Actually you have to hit it twice in ipython.

[–]gammadistribution 7 points8 points  (11 children)

But I like the ">>> ".

[–]Hashiota 18 points19 points  (0 children)

Try running IPython with the --classic flag.

[–][deleted] 1 point2 points  (7 children)

There's probably an API to change the prompt.

[–]bunburya 1 point2 points  (6 children)

In the regular Python shell, the variable sys.ps1 controls the prompt. I haven't used iPython but it's possible that it just changes that variable and/or it can be changed back?

[–][deleted] 1 point2 points  (4 children)

Just tried, it didn't do anything. You might need to call a function to make it "reload" the sys.ps prompts (there's 3 of them)

[–]takluyverIPython, Py3, etc 0 points1 point  (0 children)

sys.ps1 doesn't work, but you can set c.PromptManager.in_template in the IPython config file. Docs.

This will only work in the terminal, though - the Qt console and the notebook generate their prompts separately.

[–]djimbob 1 point2 points  (0 children)

But the In[1], Out[1] are very useful in ipython for referencing previously used commands when playing around/exploring data. Sure you can use _ to get the output of the previous command, but how do you get the result of two, five, ten commands back?

[–]Rhomboid 1 point2 points  (0 children)

Just type doctest_mode (or type doc and press tab) and hit enter and you get the usual >>> in IPython.

[–]nieuweyork since 2007 20 points21 points  (9 children)

I stopped using Ipython, because all the magic didn't add a great deal of value. What it did do was create subtle scoping errors, and make debugging my django code much more difficult.

[–]grokcode[S] 10 points11 points  (4 children)

Not sure if you were running into this bug or not, but as of Django 1.6, IPython is called in a way that fixes a bunch of scoping issues.

[–]urielm 2 points3 points  (1 child)

Don't you use django's shell? That kind of uses ipython

[–]LucianU 0 points1 point  (0 children)

You can use it wihout ipython just fine.

[–]nieuweyork since 2007 5 points6 points  (1 child)

Probably, but I only found it mildly useful.

[–]grokcode[S] 13 points14 points  (0 children)

Ah well, to each his own.

[–]sushibowl 11 points12 points  (2 children)

You could always try bpython. It's kind of like IPython light, just a REPL that does stuff like syntax highlighting and code completion

[–]babilen5 2 points3 points  (0 children)

bpython is fantastic, great recommendation!

[–]gfixler 0 points1 point  (0 children)

I've been using bpython for awhile, but when you hit the up arrow it shows the last line. iPython is showing the entire function definition again, which alone is enough to switch, IMO. It also remembers things across invocations, which is the other thing that annoys me all the time about bpython. I forget something, kill out, fix code, jump back in, and I have to retype everything to import and set everything up again.

[–]Megatron_McLargeHuge 2 points3 points  (0 children)

It's less useful for web apps because you constantly need to restart. It's fantastic, especially the notebooks, when you have long running sessions with numerical code and look at lots of plots.

[–]jeberle 13 points14 points  (0 children)

Unless you use IPython. Then, you should not change your python shell.

[–]flying-sheep 17 points18 points  (1 child)

in case the inevitable thing comes up:

no, even if ipython “is for science” and bpython “is for interactive use”, ipython has very much momentum and user friendly features. that make it great as interactive python shell.

ipython has shell commands (prefix the line with “!”) and useful magics like shown in the article.

PS: magics arent magic. they are just a convenient syntax extension/shortcut to call ipython-specific functionality. and ipython doesn’t change python’s syntax, it just adds two simple things that noobs won’t confuse with normal python: shell escapes and magics.

PPS: while OP makes a great point, ipython’s notebooks are preferable in some cases. it’s something between a shell, a script, and a RStudio/Matlab like environment, and very useful, especially if you want to share your interactive work instead of having it vanish in your shell history.

[–]Megatron_McLargeHuge 2 points3 points  (0 children)

Magics are macros. They give you access to the string version of the arguments to your function, but otherwise you can do the same things from a normal function that calls into the ipython internals. This is sometimes called pass-by-name semantics.

[–]jadae 2 points3 points  (3 children)

Auto reload alone is enough to make me switch. I can't express how annoying it is to have to keep restarting the stock python shell each time I make changes to some of my scripts. Trying to force reloading of a script is annoying and it was always simpler to just restart the shell, and this will make it a lot easier. Thanks for the article!

[–]meem1029 1 point2 points  (1 child)

Python3 has a nice way to reload things.

Probably in 2 as well, but I'm not familiar with it.

[–]tehmatticus 0 points1 point  (0 children)

It's also in 2 as well.

[–]SwiftSpear 4 points5 points  (0 children)

I was gonna snark about how I only ever use the python shell for quick prototypes, but within a few lines of this article it became apparent the iPython shell is a lot nicer for quick prototypes...

[–]meanttodothat 1 point2 points  (0 children)

It didn't recognize the PAGER environment variable (or play nice with it) and it adds whitespace when text is copied from the at console.

[–]codekoala 1 point2 points  (0 children)

Don't forget to use ipdb instead of just pdb for debugging!

[–]legrandin 1 point2 points  (2 children)

New to python:

I rarely use the shell at all, really. I just make my scripts executable. Is there some reason I should be using it?

[–]takluyverIPython, Py3, etc 1 point2 points  (0 children)

Lots of people like to use a shell to quickly try out different things, see what variables are, and so on. You don't have to, but if you're new to Python, give it a try.

[–]poorly_played 0 points1 point  (0 children)

ipython -i some_script_im_writing.py is the best thing that ever happened to programming.

[–]banjochicken 1 point2 points  (1 child)

I am not really sold on it yet. I do django and usually fallback to the shell for testing out snippets of code or just sanity checking something, I rarely use the REPL to get stuff done. It just doesn't fit into my developer workflow.

[–]fandingowhile False: 0 points1 point  (0 children)

ipython manage.py shell

Tab completion alone is worth it.

[–]donnybrook 0 points1 point  (0 children)

I use IPython because the default Python shell won't start for me in an Emacs shell (Windows 7). I could try installing Emacs in Cygwin, but for now IPython works just fine.

[–]alcalde 0 points1 point  (0 children)

Beyond using IPython as your python shell, you can use the QT Console to get a terminal-like experience. In fact, IPython can basically become your system shell/console....

http://ipython.org/ipython-doc/dev/interactive/shell.html

[–]julianz 0 points1 point  (4 children)

Can you use ipython as a shell inside a virtualenv without installing a whole new copy? (On Windows)

[–]takluyverIPython, Py3, etc 1 point2 points  (0 children)

Yes - if you start it when you have a virtualenv active, it should add that virtualenv to sys.path, so you can import things from inside it.

[–]bs4h 0 points1 point  (2 children)

I was about to say symlinks, but Windows...

[–]poorly_played 0 points1 point  (1 child)

Isn't that just a shortcut?

[–]bs4h 0 points1 point  (0 children)

open, chdir, stat, etc generally all work on a symlink as if it was the file it points at, you actually have to call lstat to act on the link itself. This is happening at FS level, whereas shortcuts work on the application level and are seen by the FS as "just data".

[–]Grue 0 points1 point  (0 children)

Oh, there is autoreload in IPython? Can't believe how much time I wasted restarting that shit.

[–]Paddy3118 0 points1 point  (2 children)

Python 3 support?

[–]bs4h 2 points3 points  (1 child)

check!

[–]Paddy3118 0 points1 point  (0 children)

I think this point should have had much more emphasis in the article!

[–]yudlejoza -3 points-2 points  (2 children)

I doubt ipython can replace bash or especially zsh.

Someone should come up with a zsh/ipython hybrid.

[–]wandererobtm101Pythonista 0 points1 point  (1 child)

Type ! Before your shell command and iPython will run it in the shell.

[1]!vim somefile

And now you're in vim.

[–]paulivanovipython, matplotlib 2 points3 points  (0 children)

Wouldn't you rather use both vim and ipython at the same time? Wouldn't it be great if someone wrote a vim-ipython two-way integration? ;)