Dear python shell:
Apr. 23rd, 2010 02:34 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
![[community profile]](https://www.dreamwidth.org/img/silk/identity/community.png)
Most of the time when I want to quit using you, I do something like this:
I am not sure why, if you know enough about what I want to give me a warning message about what I should Properly Do, you couldn't just exit and save me the headdesking trouble!
Other than that, I love you, so I am hoping you have a Really Good reason for this that I just don't know about.
>>> exit Use exit() or Ctrl-D (i.e. EOF) to exit
I am not sure why, if you know enough about what I want to give me a warning message about what I should Properly Do, you couldn't just exit and save me the headdesking trouble!
Other than that, I love you, so I am hoping you have a Really Good reason for this that I just don't know about.
(no subject)
Date: 2010-04-24 05:55 am (UTC)(no subject)
Date: 2010-04-24 06:43 am (UTC)fireCtrl-D :)(no subject)
Date: 2010-04-24 08:39 am (UTC)(no subject)
Date: 2010-05-01 01:14 pm (UTC)Easy Explanation: It is because most programmers are pathological sticklers for exactness.
(no subject)
Date: 2010-05-01 05:46 pm (UTC)(no subject)
Date: 2010-05-01 10:53 pm (UTC)(no subject)
Date: 2010-05-01 10:57 pm (UTC)(no subject)
Date: 2011-03-01 09:43 am (UTC)Basically, Python has a module called
site.py
which provides a lot of Cool Stuff. One of the things it does is scan the standard prefixes for.pth
files, which are then appended toPYTHONPATH
— so include a.pth
file with relative paths in your distutils scripts viadata_files = [("lib/site-packages", "your_data_file.pth")]
if you want to install to a sub-folder oflib/site-packages
, which wouldn't automatically be checked (this bit me with the Windows-compiled binary for thepython-rsvg
module — it installs tolib/site-packages/gtk-2.0/rsvg.pyd
, and that's never put intoPYTHONPATH
, so Python never knows that you havepython-rsvg
installed so trying to import it always fails.) — but it also providesexit
andquit
.These are neither statements (like
print
, which, confusingly enough, has ceased to be a statement in Python 3.0 and is now a function — and it can be treated like a function from Python 2.7 onwards) nor functions (though they're callable).They're actually instances of
site.Quitter
— which isn't available as a class viasite.Quitter
; this further confuses matters — which you can find out with:>>> type(exit)
<class 'site.Quitter'>
>>> type(quit)
<class 'site.Quitter'>
(Interestingly enough:
>>> exit == quit
False
>>> type(exit) is type(quit)
True
They're both instances of
site.Quitter
, but not the same instance.)So, as they're instances rather than statements, one cannot just execute
exit
orquit
as you might expect (another digression: someone filed a bug regarding the site-providedexit
andquit
methods polluting the builtin namespace, but it was not acted upon because some people have grown to rely onexit
andquit
being available outside of the interpreter — so it seems the original intent was that these were only to be available via the interpreter!). Instead, you have to call them as functions, just like all other built-in functions (dir
,sorted
, and, related but explained later,help
).To get around the fact that most people expect
exit
andquit
to be statements, it was decided (at some point in time, by person or persons unknown) to give them a little dash of "magic". To side-step the issue and come at it from another angle, when one types the name of a variable (almost everything in Python is a variable), it prints an internal representation of that variable.For other built-ins, such as
dir
, callingrepr(dir)
returns'<builtin function dir>'
, for example. Thus:>>> dir
<built-in function dir>
This is because functions (and, built-in functions, which derive from the main function type), by default, provide a
__repr__
method; this magic method is called wheneverrepr
is called — eitherrepr
looks for this method, or this method is called instead ofrepr
, or this method callsrepr
: I can never remember the exact order of things!Thus, any class which defines a
__repr__
method, when an instance of that class is created, and its variable name is typed into the interpreter, will have that method called, and the value it returns will be printed. Therefore, we can do the following:>>> class ReprTester (object):
... def __repr__ (self):
... return "Executing me as an instance calls repr(me) and displays the result!"
...
>>> test = ReprTester()
>>> test
Executing me as an instance calls repr(me) and displays the result!
So, when one performs the following in the interpreter:
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
You're actually indirectly calling
print(repr(exit))
, and that's the "magic" I mentioned earlier. So now, whenever someone callsexit
(orquit
), they get a pretty little reminder telling them to callexit()
(orquit()
) instead.Fun side-point: because the code directly calls
__repr__
of theexit
object, we can actually create a new class that actually does exit whenever it's called as though it were a statement — though this has the side effect of whenever you callrepr(exit)
your interpreter exits:>>> class FancyQuitter (object):
... def __repr__ (self):
... __builtins__.exit()
...
>>> exit = FancyQuitter()
>>> exit
persson@persson:~
So, if you really, really couldn't stand it, there's probably a way to use this object to consistently replace the built-in
exit
andquit
objects whenever you start the interpreter. However, I just prefer to useCtrl-D
!(And one final side-note: I think the messages are different across platforms, but
Ctrl-D
doesn't work on Windows. Instead, you have to useCtrl-Z
. For someone who switches consistently between platforms, I've developed the following technique:Ctrl-C Ctrl-D Ctrl-Z Ctrl-C Ctrl-Z Ctrl-D
.Doing this in quick succession usually results in the thing finally oh finally quitting. Alternately, hitting the Window manager's close button or (though not on Windows — this not working is very annoying to me)
Alt-F4
is a sure-fire way to end that pesky, annoying, infuriating interpreter!)(Oh, a final final side-note: while I exclaim that it's
__repr__
that does all of the 'good' work above, there's every chance that__repr__
is actually just callingstr(exit)
and it's the__str__
function that prints the pretty statement. So, where or when necessary, replace all references to__repr__
with__str__
!)(Okay, now a final note, because I mentioned it earlier:
help
is exactly the same thing, except it does documentation rather than quitting the program, and is an instance ofsite._Helper
— another "invisible" class.)