Python: Яка різниця між __builtin__ та __builtins__?


76

Я сьогодні кодував і щось помітив. Якщо я відкрию новий сеанс перекладача (IDLE) і перевірю, що визначено dirфункцією, я отримую це:

$ 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

Зверніть увагу на останній рядок.

Отже, моє запитання:

  • Чи є псевдонім іншого?

  • Чи планують хлопці з Python позбутися одного з них?

  • Що слід використовувати для власних програм?

  • Як щодо Python 3?

  • Будь-яка інформація цінна!

Важливо:

Я використовую Python 2.7.2+ на Ubuntu.


що стосується мого коду, те, що, здається, працює, використовуйте, import builtinsдив. це для прикладу: ( stackoverflow.com/questions/61084916/… )
Буратіно,

Відповіді:


69

Прямо з документації на python: http://docs.python.org/reference/executionmodel.html

За замовчуванням, коли він знаходиться в __main__модулі, __builtins__це вбудований модуль __builtin__(примітка: немає 's'); коли є в будь-якому іншому модулі, __builtins__є псевдонімом для словника самого __builtin__модуля.

__builtins__ може бути встановлений на створений користувачем словник для створення слабкої форми обмеженого виконання.

Подробиці реалізації CPython: Користувачі не повинні торкатися __builtins__; це суто деталь реалізації. Користувачі, які хочуть замінити значення у вбудованому просторі імен, повинні import використовувати __builtin__модуль (не 's') та відповідно змінювати його атрибути. Простір імен для модуля створюється автоматично під час першого імпорту модуля.

Зверніть увагу, що в Python3 модуль __builtin__було перейменовано на, builtinsщоб уникнути цієї плутанини.


Чудова відповідь, велике спасибі. Чи знаєте ви щось про Python 3?
santiagobasulto

10
Як сказано в інших відповідях, для python 3 це те саме, за винятком того, що __builtin__модуль перейменовано на "вбудований" (без підкреслення). docs.python.org/dev/reference/executionmodel.html
akent

Мені все одно до подробиць. Що ніколи не призведе до того, що в моєму коді буде помилка, якщо я його використовую, модифікую тощо?
Буратіно,

23

Ви повинні використовувати __builtin__у своїх програмах (у рідкісних випадках, коли це вам потрібно), оскільки __builtins__це деталь реалізації CPython. Це може бути ідентично __builtin__або __builtin__.__dict__, залежно від контексту. Як сказано в документації :

Більшість модулів мають назву __builtins__(зверніть увагу на "s"), яка доступна як частина їх глобальних систем. Значення, __builtins__як правило, є або цим модулем, або значенням __dict__атрибута цього модуля . Оскільки це деталь реалізації, вона не може використовуватися альтернативними реалізаціями Python.

У Python 3 __builtin__перейменовано на builtinsта __builtins__залишається незмінним (тому вам слід використовувати лише builtinsв Python 3).

Гвідо хотів об’єднатися __builtin__і __builtins__, як ви можете бачити тут ("Мати __builtins__і __builtin__обох, це явно погана ідея"), але, мабуть, нічого з цього не вийшло.

Очевидно, використання __builtins__є для продуктивності - воно дає прямий доступ до, __builtin__.__dict__коли використовується в не основному модулі, а отже, усуває один рівень опосередкованості.


Що ви маєте на увазі під "не основним модулем"? Ви маєте на увазі модулі, окрім builtins?
Екрем Дінчель

використовуючи __builtin__дає мені помилку: NameError: name '__builtin__' is not defined. Який правильний спосіб отримати доступ до цього, що не ламається?
Буратіно

9

__builtin__- це модуль, що містить вбудовані функції та типи. Той факт, що ім'я __builtins__доступне, що містить однакові речі, є деталлю реалізації. Іншими словами, якщо вам потрібно скористатися одним із них, виконайте, import __builtin__а потім використовуйте __builtin__. Дивіться документацію .


Мені все одно до подробиць. Що ніколи не призведе до того, що в моєму коді буде помилка, якщо я його використовую, модифікую тощо?
Буратіно,

Я думаю, що ви мали на увазі, import builtinsнаприклад, див. Цей код stackoverflow.com/a/61085162/3167448
Буратіно

2

Ви можете зрозуміти це, наприклад, наступний код. при запуску cpython cpython завантажує __builtin__модулі у глобальний простір імен

імпортувати __builtin__як__builtins__


@Pinocchio, чому ти всюди просиш це спамувати? можливо, якби ви звернули увагу на деталі або попросили докладніше, ви зрозуміли б, чому це може чи не спричинить помилку, залежно від того, як ви її використовуєте.
Перерва

0

__builtins__Модуль не слід плутати з __builtin__модулем. Імена, звичайно, настільки подібні, що це, як правило, призводить до певної плутанини серед нових програмістів Python, які зайшли так далеко. __builtins__Модуль складається з набору вбудованих імен для вбудованих елементів простору імен. Більшість, якщо не всі, цих імен походять від __builtin__модуля, який є модулем вбудованих функцій, винятків та інших атрибутів. У стандартному виконанні Python __builtins__містить усі імена з __builtin__. У Python раніше існувала обмежена модель виконання, яка дозволяла модифікувати місця, __builtins__звідки ключові фрагменти __builtin__були випущені, щоб створити середовище пісочниці.

Однак через недоліки безпеки та труднощі, пов’язані з його ремонтом, обмежене виконання більше не підтримується в Python (станом на 2.3).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.