Python: Quelle est la différence entre builtin et builtins?
Je codais aujourd'hui et j'ai remarqué quelque chose. Si j'ouvre une nouvelle session d'interpréteur (IDLE) et vérifie ce qui est défini avec la fonction dir
, j'obtiens ceci:
$ 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
Veuillez noter la dernière ligne.
Donc, ma question Est:
Est tout un alias de l'autre?
Les gars de Python prévoient-ils de se débarrasser de l'un d'entre eux?
Que dois-je utiliser pour mes propres programmes?
Et Python 3?
Tout l'information est précieuse!
Important:
J'utilise python 2.7.2 + sur Ubuntu.
4 réponses
Directement à partir de la documentation python: http://docs.python.org/reference/executionmodel.html
Par défaut, lorsque dans le
__main__
module,__builtins__
est l' module intégré__builtin__
(note: Aucun 's'); quand dans n'importe quel autre module, {[1] } est un alias pour le dictionnaire du__builtin__
module lui-même.
__builtins__
peut être défini sur un dictionnaire créé par l'utilisateur pour créer un forme faible d'exécution restreinte.Disponible détail de l'implémentation: Les utilisateurs ne doivent pas toucher
__builtins__
; c'est strictement un détail d'implémentation. Utilisateur vouloir remplacer les valeurs dans l'espace de noms builtins devraitimport
le module__builtin__
(no 's') et modifier ses attributs approprié. L'espace de noms d'un module est automatiquement créé la première fois qu'un module est importé.
Notez qu'en Python3, le module __builtin__
a été renommé en builtins
pour éviter une partie de cette confusion.
, Vous devez utiliser __builtin__
dans vos programmes (dans les rares cas où vous en avez besoin), car __builtins__
est un détail d'implémentation de Disponible. Il peut être soit identique à __builtin__
, soit à __builtin__.__dict__
, selon le contexte. Comme la documentation dit:
La plupart des modules ont le nom
__builtins__
(notez le 's') mis à disposition dans le cadre de leurs globals. La valeur de__builtins__
est normalement soit ce module, soit la valeur de l'attribut__dict__
de ce module. Puisque c'est une implémentation détail, il ne peut pas être utilisé par d'autres implémentations de Python.
Dans Python 3, __builtin__
a été renommé en builtins
, et __builtins__
reste le même (donc vous ne devriez utiliser que builtins
dans Python 3).
Guido voulu unir __builtin__
et __builtins__
, comme vous pouvez le voir ici ("Avoir __builtins__
et __builtin__
les deux est clairement une mauvaise idée.") mais apparemment il n'en fut rien.
, Apparemment, l'utilisation de __builtins__
est pour la performance - il donne un accès direct à __builtin__.__dict__
dans le cas de non-principal module, et supprime donc un niveau d'indirection.
__builtin__
est un module contenant les fonctions et les types. Le fait qu'un nom __builtins__
soit disponible contenant les mêmes choses est un détail d'implémentation. En d'autres termes, si vous devez utiliser l'un d'entre eux, faites import __builtin__
puis utilisez __builtin__
. Voir la documentation.
Vous pouvez les comprendre comme le code suivant.
lorsque cpython est démarré, cpython charge les modules __builtin__
dans l'espace de noms global
Importer __builtin__
comme __builtins__