Wat is het verschil tussen __builtin__ en __builtins__?

Ik was vandaag aan het coderen en merkte iets op. Als ik een nieuwe tolksessie (IDLE) open en controleer wat er is gedefinieerd met de functie dir, krijg ik dit:

$ 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

Let op de laatste regel.

Dus mijn vraag is:

  • Is er een alias van de andere?

  • Zijn de Python-mannen van plan om van een van deze af te komen?

  • Wat moet ik gebruiken voor mijn eigen programma’s?

  • Hoe zit het met Python 3?

  • Alle informatie is waardevol!

Belangrijk:

Ik gebruik Python 2.7.2+ op Ubuntu.


Antwoord 1, autoriteit 100%

Rechtstreeks uit de python-documentatie:
http://docs.python.org/reference/executionmodel.html

Standaard, wanneer in de __main__module, is __builtins__de
ingebouwde module __builtin__(let op: geen ‘s’); wanneer in een andere
module, __builtins__is een alias voor het woordenboek van de
__builtin__module zelf.

__builtins__kan worden ingesteld op een door de gebruiker gemaakt woordenboek om een
zwakke vorm van beperkte uitvoering.

CPython-implementatiedetail:gebruikers mogen __builtins__niet aanraken; het is strikt een uitvoeringsdetail. Gebruikers
die waarden in de ingebouwde naamruimte willen overschrijven, moet import
de __builtin__(geen ‘s’) module en pas de attributen aan
op gepaste wijze. De naamruimte voor een module wordt automatisch aangemaakt door de
eerste keer dat een module wordt geïmporteerd.

Merk op dat in Python3 de module __builtin__is hernoemd naar builtinsom een ​​deel van deze verwarring te voorkomen.


Antwoord 2, autoriteit 34%

Je moet __builtin__in je programma’s gebruiken (in de zeldzame gevallen dat je het nodig hebt), omdat __builtins__een implementatiedetail van CPython is. Het kan ofwel identiek zijn aan __builtin__, of aan __builtin__.__dict__, afhankelijk van de context. Zoals de documentatiezegt:

De meeste modules hebben de naam __builtins__(let op de ‘s’) beschikbaar gesteld als onderdeel van hun globals. De waarde van __builtins__is normaal gesproken deze module of de waarde van het kenmerk __dict__van deze module. Aangezien dit een implementatiedetail is, mag het niet worden gebruikt door alternatieve implementaties van Python.

In Python 3 is __builtin__hernoemd naar builtins, en __builtins__blijft hetzelfde (gebruik dus alleen builtinsin Python 3)).

Guido wilde __builtin__en __builtins__verenigen, zoals je kunt zien hier(“Het is duidelijk een slecht idee om __builtins__en __builtin__beide te hebben.”) , maar er is blijkbaar niets van terecht gekomen.

Blijkbaar is het gebruik van __builtins__voor prestaties – het geeft directe toegang tot __builtin__.__dict__bij gebruik in een niet-hoofdmodule, en verwijdert daarom één niveau van indirectheid .


Antwoord 3, autoriteit 12%

__builtin__is een module die de ingebouwde functies en typen bevat. Het feit dat een naam __builtins__beschikbaar is die dezelfde dingen bevat, is een implementatiedetail. Met andere woorden, als je er een moet gebruiken, voer dan import __builtin__uit en gebruik dan __builtin__. Zie de documentatie.


Antwoord 4, autoriteit 3%

Je kunt deze begrijpen zoals de volgende code.
wanneer cpython wordt gestart, laadt cpython __builtin__modules in globale naamruimte

importeer __builtin__als __builtins__


Antwoord 5

De __builtins__module moet niet worden verward met de __builtin__module. De
namen lijken natuurlijk zo op elkaar dat dit tot verwarring kan leiden bij nieuwe Python
programmeurs die zo ver zijn gekomen.
De module __builtins__bestaat uit een set ingebouwdenamen voor de ingebouwdenaamruimte. De meeste, zo niet alle, van deze namen komen uit de
__builtin__module, dit is een module van de ingebouwde functies, uitzonderingen en andere
attributen.
In standaard Python-uitvoering bevat __builtins__alle namen van
__builtin__. Python had vroeger een beperkt uitvoeringsmodel dat wijziging van __builtins__mogelijk maakte, waarbij belangrijke stukken van __builtin__werden weggelaten om een sandbox-omgeving te creëren.

Vanwege de beveiligingsfouten en de moeilijkheid bij het repareren ervan,
beperkte uitvoering wordt niet langer ondersteund in Python (vanaf 2.3).

Other episodes