2012-06-24 16 views
54

Estaba codificando hoy y noté algo. Si abro una nueva sesión de intérprete (en reposo) y comprobar lo que se define con la función dir me sale esto:Python: ¿Cuál es la diferencia entre __builtin__ y __builtins__?

$ 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 

Tenga en cuenta la última línea.

lo tanto, mi pregunta es:

  • ¿Alguno de un alias de la otra?

  • ¿Los chicos de Python planean deshacerse de uno de esos?

  • ¿Qué debo usar para mis propios programas?

  • ¿Qué hay de Python 3?

  • ¡Cualquier información es valiosa!

Importante:

estoy usando Python 2.7.2+ en Ubuntu.

Respuesta

48

Directamente de la documentación de Python: http://docs.python.org/reference/executionmodel.html

Por defecto, cuando en el módulo __main__, __builtins__ es el módulo incorporado __builtin__ (nota: no hay 's'); cuando en cualquier otro módulo , __builtins__ es un alias para el diccionario del módulo __builtin__.

__builtins__ se puede establecer en un diccionario creado por el usuario para crear una forma débil de ejecución restringida.

CPython implementación detalle: Los usuarios no deben tocar __builtins__; es estrictamente un detalle de implementación. Los usuarios que desean sobrescribir los valores en el espacio de nombres builtins deberían import el módulo __builtin__ (no 's') y modificar sus atributos de forma adecuada. El espacio de nombre para un módulo se crea automáticamente el la primera vez que se importa un módulo.

Nótese que en python3, el módulo __builtin__ ha sido renombrado a builtins para evitar algunos de esta confusión.

+0

Gran respuesta, muchas gracias. ¿Sabes algo sobre Python 3? – santiagobasulto

+8

Como otras respuestas han dicho que es lo mismo para python 3 excepto que el módulo '__builtin__' se renombra a" builtins "(sin guiones bajos). http://docs.python.org/dev/reference/executionmodel.html – akent

6

__builtin__ es un módulo que contiene las funciones y tipos incorporados. El hecho de que un nombre __builtins__ esté disponible conteniendo las mismas cosas es un detalle de implementación. En otras palabras, si necesita usar uno de ellos, haga import __builtin__ y luego use __builtin__. Ver the documentation.

17

Debe usar __builtin__ en sus programas (en los pocos casos que lo necesite), porque __builtins__ es un detalle de implementación de CPython.Puede ser idéntico al __builtin__, o al __builtin__.__dict__, dependiendo del contexto. Como dice the documentation:

mayoría de los módulos tienen el nombre __builtins__ (nótese la 's') puso a disposición como parte de sus variables globales. El valor de __builtins__ es normalmente este módulo o el valor del atributo __dict__ de este módulo. Como se trata de un detalle de implementación, no puede ser utilizado por implementaciones alternativas de Python.

En Python 3, __builtin__ ha sido renombrado a builtins y __builtins__ sigue siendo el mismo (lo que sólo debe utilizar builtins en Python 3).

Guido quería unir __builtin__ y __builtins__, como se puede ver here ("Tener __builtins__ y __builtin__ tanto es claramente una mala idea."), Pero al parecer no pasó nada.

Al parecer, el uso de __builtins__ es para un rendimiento - que da acceso directo a __builtin__.__dict__ cuando se utiliza en un módulo no principal, y por lo tanto elimina un nivel de indirección.

1

Puede entender estos como el siguiente código. cuando se inicia CPython, carga CPython __builtin__ módulos en espacio de nombres global

importación __builtin__ como __builtins__

Cuestiones relacionadas