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, moetimport
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 builtins
om 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 builtins
in 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).