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.

58
demandé sur Zero Piraeus 2012-06-25 01:56:06

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 devrait import 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.

53
répondu akent 2013-08-14 07:53:01

, 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.

18
répondu interjay 2012-06-24 22:11:48

__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.

7
répondu BrenBarn 2012-06-24 22:06:48

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__

2
répondu lslab 2013-01-14 09:58:19