2012-06-24 19 views
54

Oggi stavo programmando e ho notato qualcosa. Se apro una nuova sessione di interprete (IDLE) e controllare che cosa è definito con la funzione dir ottengo questo:Python: Qual è la differenza tra __builtin__ e __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 

Si prega di notare l'ultima riga.

Quindi, la mia domanda è:

  • è un qualsiasi un alias dell'altro?

  • I ragazzi di Python stanno pianificando di sbarazzarsi di uno di questi?

  • Cosa devo usare per i miei programmi?

  • Che dire di Python 3?

  • Qualsiasi informazione è preziosa!

Importante:

sto usando Python 2.7.2+ su Ubuntu.

risposta

48

Direttamente dalla documentazione python: http://docs.python.org/reference/executionmodel.html

Per impostazione predefinita, quando nel modulo __main__, __builtins__ è la modulo incorporato __builtin__ (nota: no 's'); quando in qualsiasi altro modulo , __builtins__ è un alias per il dizionario del modulo __builtin__ .

__builtins__ può essere impostato su un dizionario creato dall'utente per creare una forma debole di esecuzione limitata.

Dettaglio implementazione CPython: Gli utenti non devono toccare __builtins__; è strettamente un dettaglio di implementazione. Gli utenti che desiderano sovrascrivere i valori nello spazio dei nomi builtin devono import il modulo __builtin__ (no 's') e modificarne gli attributi in modo appropriato. Lo spazio dei nomi per un modulo viene creato automaticamente la prima che un modulo venga importato.

Si noti che nel python3, il modulo __builtin__ è stato rinominato in builtins per evitare alcuni di questa confusione.

+0

Grande risposta, grazie mille. Sai qualcosa riguardo Python 3? – santiagobasulto

+8

Come altre risposte hanno detto che è lo stesso per python 3 tranne che il modulo '__builtin__' è rinominato in" builtins "(senza caratteri di sottolineatura). http://docs.python.org/dev/reference/executionmodel.html – akent

6

__builtin__ è un modulo contenente funzioni e tipi incorporati. Il fatto che un nome __builtins__ sia disponibile contenente le stesse cose è un dettaglio di implementazione. In altre parole, se è necessario utilizzare uno di essi, fare import __builtin__ e quindi utilizzare __builtin__. Vedi the documentation.

17

È necessario utilizzare __builtin__ nei programmi (nei rari casi in cui è necessario), perché __builtins__ è un dettaglio di implementazione di CPython.Può essere identico a __builtin__ o a __builtin__.__dict__, a seconda del contesto. Come the documentation dice:

maggior parte dei moduli hanno il nome __builtins__ (notare la 's') reso disponibile come parte dei loro globali. Il valore di __builtins__ è normalmente questo modulo o il valore dell'attributo __dict__ di questo modulo. Poiché si tratta di un dettaglio di implementazione, potrebbe non essere utilizzato da implementazioni alternative di Python.

In Python 3, __builtin__ è stata rinominata in builtins, e __builtins__ rimane lo stesso (così si dovrebbe usare solo builtins in Python 3).

Guido voluto unire __builtin__ e __builtins__, come si può vedere here ("Avere __builtins__ e __builtin__ entrambi è chiaramente una cattiva idea."), Ma a quanto pare se ne fece nulla.

A quanto pare l'utilizzo di __builtins__ è per le prestazioni: consente l'accesso diretto a __builtin__.__dict__ quando utilizzato in un modulo non principale e pertanto rimuove un livello di riferimento indiretto.

1

È possibile comprendere questi come il seguente codice. all'avvio CPython, carico CPython __builtin__ moduli in namespace globale

importazione __builtin__ come __builtins__

Problemi correlati