This is actually really confusing and it annoyed me once so I looked into it!
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 to PYTHONPATH — so include a .pth file with relative paths in your distutils scripts via data_files = [("lib/site-packages", "your_data_file.pth")] if you want to install to a sub-folder of lib/site-packages, which wouldn't automatically be checked (this bit me with the Windows-compiled binary for the python-rsvg module — it installs to lib/site-packages/gtk-2.0/rsvg.pyd, and that's never put into PYTHONPATH, so Python never knows that you have python-rsvg installed so trying to import it always fails.) — but it also provides exit and quit.
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 via site.Quitter; this further confuses matters — which you can find out with:
>>> 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 or quit as you might expect (another digression: someone filed a bug regarding the site-provided exit and quit methods polluting the builtin namespace, but it was not acted upon because some people have grown to rely on exit and quit 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 and quit 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, calling repr(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 whenever repr is called — either repr looks for this method, or this method is called instead of repr, or this method calls repr: 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 calls exit (or quit), they get a pretty little reminder telling them to call exit() (or quit()) instead.
Fun side-point: because the code directly calls __repr__ of the exit 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 call repr(exit) your interpreter exits:
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 and quit objects whenever you start the interpreter. However, I just prefer to use Ctrl-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 use Ctrl-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 calling str(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 of site._Helper — another "invisible" class.)
no subject
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.)