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