I was coding today and noticed something. If I open a new interpreter session (IDLE) and check what’s defined with the dir
function I get this:
$ python >>> dir() ['__builtins__', '__doc__', '__name__', '__package__'] >>> dir(__builtins__) ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip'] >>> import __builtin__ ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip'] >>> dir(__builtin__) == dir(__builtins__) # They seem to have the same things True
Please note the last line.
So, my question is:
- Is any an alias of the other one?
- Are the Python guys planning to get rid of one of those?
- What should I use for my own programs?
- What about Python 3?
- Any information is valuable!
Important:
I’m using Python 2.7.2+ on Ubuntu.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Straight from the python documentation:
http://docs.python.org/reference/executionmodel.html
By default, when in the
__main__
module,__builtins__
is the
built-in module__builtin__
(note: no ‘s’); when in any other
module,__builtins__
is an alias for the dictionary of the
__builtin__
module itself.
__builtins__
can be set to a user-created dictionary to create a
weak form of restricted execution.CPython implementation detail: Users should not touch
__builtins__
; it is strictly an implementation detail. Users
wanting to override values in the builtins namespace shouldimport
the__builtin__
(no ‘s’) module and modify its attributes
appropriately. The namespace for a module is automatically created the
first time a module is imported.
Note that in Python3, the module __builtin__
has been renamed to builtins
to avoid some of this confusion.
Method 2
You should use __builtin__
in your programs (in the rare cases that you need it), because __builtins__
is an implementation detail of CPython. It may either be identical to __builtin__
, or to __builtin__.__dict__
, depending on the context. As the documentation says:
Most modules have the name
__builtins__
(note the ‘s’) made available as part of their globals. The value of__builtins__
is normally either this module or the value of this modules’s__dict__
attribute. Since this is an implementation detail, it may not be used by alternate implementations of Python.
In Python 3, __builtin__
has been renamed to builtins
, and __builtins__
remains the same (so you should only use builtins
in Python 3).
Guido wanted to unite __builtin__
and __builtins__
, as you can see here (“Having __builtins__
and __builtin__
both is clearly a bad idea.”) , but apparently nothing came of it.
Apparently the use of __builtins__
is for performance – it gives direct access to __builtin__.__dict__
when used in a non-main module, and therefore removes one level of indirection.
Method 3
__builtin__
is a module containing the built-in functions and types. The fact that a name __builtins__
is available containing the same things is an implementation detail. In other words, if you need to use one of them, do import __builtin__
and then use __builtin__
. See the documentation.
Method 4
You can understand these like following code.
when cpython is started, cpython load __builtin__
modules into global namespace
import __builtin__
as __builtins__
Method 5
The __builtins__
module should not be confused with the __builtin__
module. The
names, of course, are so similar that it tends to lead to some confusion among new Python
programmers who have gotten this far.
The __builtins__
module consists of a set of builtin names for the built-ins namespace. Most, if not all, of these names come from the
__builtin__
module, which is a module of the built-in functions, exceptions, and other
attributes.
In standard Python execution, __builtins__
contains all the names from
__builtin__
. Python used to have a restricted execution model that allowed modification of __builtins__
where key pieces from __builtin__
were left out to create a sandbox environment.
However, due its security flaws and the difficulty involved with repairing it,
restricted execution is no longer supported in Python (as of 2.3).
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0