Python: Was ist der Unterschied zwischen __builtin__ und __builtins__?

75

Ich habe heute programmiert und etwas bemerkt. Wenn ich eine neue Dolmetschersitzung (IDLE) öffne und überprüfe, was mit der dirFunktion definiert ist, erhalte ich Folgendes :

$ 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

Bitte beachten Sie die letzte Zeile.

Meine Frage lautet also:

  • Ist irgendein Alias ​​des anderen?

  • Planen die Python-Leute, eines davon loszuwerden?

  • Was soll ich für meine eigenen Programme verwenden?

  • Was ist mit Python 3?

  • Jede Information ist wertvoll!

Wichtig:

Ich verwende Python 2.7.2+ unter Ubuntu.

Santiagobasulto
quelle
Was meinen Code betrifft , scheint dies zu funktionieren. import builtinsSehen Sie sich dies als Beispiel an: ( stackoverflow.com/questions/61084916/… )
Pinocchio

Antworten:

68

Direkt aus der Python-Dokumentation: http://docs.python.org/reference/executionmodel.html

Standardmäßig befindet sich im __main__Modul __builtins__das integrierte Modul __builtin__(Hinweis: no 's'). Wenn in einem anderen Modul, __builtins__ist ein Alias ​​für das Wörterbuch des __builtin__Moduls selbst.

__builtins__ kann auf ein vom Benutzer erstelltes Wörterbuch festgelegt werden, um eine schwache Form der eingeschränkten Ausführung zu erstellen.

Details zur CPython-Implementierung: Benutzer sollten nicht berühren __builtins__. Es handelt sich ausschließlich um ein Implementierungsdetail. Benutzer, die Werte im eingebauten Namespace überschreiben möchten, sollten import das __builtin__Modul (no 's') verwenden und seine Attribute entsprechend ändern. Der Namespace für ein Modul wird beim ersten Import eines Moduls automatisch erstellt.

Beachten Sie, dass das Modul in Python3 __builtin__umbenannt wurde builtins, um diese Verwirrung zu vermeiden.

akent
quelle
Tolle Antwort, vielen Dank. Wissen Sie etwas über Python 3?
Santiagobasulto
10
Wie andere Antworten bereits sagten, ist es für Python 3 dasselbe, außer dass das __builtin__Modul in "Builtins" (ohne Unterstriche) umbenannt wird. docs.python.org/dev/reference/executionmodel.html
akent
Die Details sind mir egal. Was wird meinen Code niemals fehlerhaft machen, wenn ich ihn verwende, ändere usw.?
Pinocchio
23

Sie sollten es __builtin__in Ihren Programmen verwenden (in den seltenen Fällen, in denen Sie es benötigen), da __builtins__es sich um ein Implementierungsdetail von CPython handelt. Es kann je nach Kontext entweder identisch mit __builtin__oder mit sein __builtin__.__dict__. Wie die Dokumentation sagt:

Die meisten Module haben den Namen __builtins__(beachten Sie die 's') als Teil ihrer Globals zur Verfügung gestellt. Der Wert von __builtins__ist normalerweise entweder dieses Modul oder der Wert des __dict__Attributs dieses Moduls . Da dies ein Implementierungsdetail ist, kann es möglicherweise nicht von alternativen Implementierungen von Python verwendet werden.

In Python 3 __builtin__wurde in umbenannt builtinsund __builtins__bleibt gleich (daher sollten Sie es nur builtinsin Python 3 verwenden).

Guido wollte sich vereinen __builtin__und __builtins__, wie Sie hier sehen können ("Haben __builtins__und __builtin__beides ist eindeutig eine schlechte Idee."), Aber anscheinend kam nichts dabei heraus.

Anscheinend dient die Verwendung von der __builtins__Leistung - sie bietet direkten Zugriff auf die __builtin__.__dict__Verwendung in einem Nicht-Hauptmodul und entfernt daher eine Indirektionsebene.

Interjay
quelle
Was meinst du mit "Nicht-Hauptmodul"? Meinen Sie Module außer builtins?
Kowalski
Verwenden __builtin__gibt mir einen Fehler : NameError: name '__builtin__' is not defined. Was ist der richtige Weg, um darauf zuzugreifen, der nicht kaputt geht?
Pinocchio
8

__builtin__ist ein Modul, das die integrierten Funktionen und Typen enthält. Die Tatsache, dass ein Name __builtins__verfügbar ist, der dieselben Dinge enthält, ist ein Implementierungsdetail. Mit anderen Worten, wenn Sie eines davon verwenden müssen, tun Sie es import __builtin__und verwenden Sie es dann __builtin__. Siehe die Dokumentation .

BrenBarn
quelle
Die Details sind mir egal. Was wird meinen Code niemals fehlerhaft machen, wenn ich ihn verwende, ändere usw.?
Pinocchio
Ich denke, was Sie meinten, war import builtinszB diesen Code stackoverflow.com/a/61085162/3167448
Pinocchio
2

Sie können diese wie den folgenden Code verstehen. Wenn cpython gestartet wird, lädt cpython __builtin__Module in den globalen Namespace

importieren __builtin__als__builtins__

lslab
quelle
@ Pinocchio, warum fragst du, ob du das überall spammen sollst? Wenn Sie auf die Details achten oder nach weiteren Details fragen, werden Sie vielleicht verstehen, warum dies einen Fehler verursachen würde oder nicht, je nachdem, wie Sie es verwenden.
Brenda