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.pywhich provides a lot of Cool Stuff. One of the things it does is scan the standard prefixes for.pthfiles, which are then appended toPYTHONPATH— so include a.pthfile 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-rsvgmodule — it installs tolib/site-packages/gtk-2.0/rsvg.pyd, and that's never put intoPYTHONPATH, so Python never knows that you havepython-rsvginstalled so trying to import it always fails.) — but it also providesexitandquit.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 == quitFalse
>>> 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
exitorquitas you might expect (another digression: someone filed a bug regarding the site-providedexitandquitmethods polluting the builtin namespace, but it was not acted upon because some people have grown to rely onexitandquitbeing 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
exitandquitto 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 wheneverrepris called — eitherreprlooks 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:
>>> exitUse 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 theexitobject, 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
exitandquitobjects 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-Ddoesn'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-F4is 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:
helpis exactly the same thing, except it does documentation rather than quitting the program, and is an instance ofsite._Helper— another "invisible" class.)