Рассмотрим возможный вопрос по смайликам при собеседовании на должность, подразумевающую знание языка программирования Python.
Задача
Имеются два выражения:
-
_+_ -
_|_
Какое из этих двух выражений чаще будет приводить к возникновению ошибки и почему?
Также нужно помнить, что смайлики в задаче написаны не питонично (не соответствуют стандарту стиля PEP 8).
Решение
В Python символ подчеркивания не является ключевым словом, поэтому, в общем случае, его можно использовать для присвоения некоторых значений переменных.
Задача сводится к рассмотрению случаев появления ошибок при сложении и при «побитовом или» (для краткости — просто «или») одной переменной. Т.е. к поиску встроенных типов (классов) Python для которых реализована одна операция и к поиску встроенных типов где реализована другая операция.
В консоли Python легко проверить, что существуют такие значения подчеркивания при которых:
-
В вычислении каждого выражения нет ошибки
>>> _ = 10 >>> _+_ 20 >>> _ = 10 >>> _|_ 10 -
В вычислении первого выражения нет ошибки
>>> _ = '10' >>> _+_ '1010' >>> _ = '10' >>> _|_ Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for |: 'str' and 'str' -
В вычислении второго выражения нет ошибки
>>> _ = {1, 0} >>> _+_ Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'set' and 'set' >>> _|_ {0, 1} -
В вычислении каждого выражения — ошибка
>>> _ = {1: 0} >>> _+_ Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'dict' and 'dict' >>> _|_ Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for |: 'dict' and 'dict'
Магия Python заключается в том, что реализация и сложения, и «или», и других операторов находится в, так называемых, «магических методах», описанных для требуемых классов.
Для сложения это метод
__add__
Для «или» это метод
__or__
В названии каждого магического метода присутствуют символы подчеркивания, по два в начале и в конце соответствующего слова.
Можно в терминале Python выполнить
>>> import builtins >>> help(builtins)
Я предпочитаю использовать документацию именно той версии Python, которую я использую в данный момент, обращаясь к web-интерфейсу модуля pydoc.
Для этого в командной строке вводим, например:
python3 -m pydoc -p 3344
и открываем в браузере документацию модуля http://localhost:3344/builtins.html.
Встроенные классы, для которых реализованы наши методы:
| __add__ | __or__ |
|---|---|
| bool | bool |
| bytearray | frozenset |
| bytes | int |
| complex | set |
| float | |
| int | |
| list | |
| str | |
| tuple |
Девять встроенных классов реализуют операцию сложения и четыре реализуют «или».
Дополнительно можно попытаться порассуждать про частоту использования базовых классов в реальных проектах, про небазовые классы и реализацию указанных выше методов для них. Вероятно, это будет положительно оценено при собеседовании.
Возможные дополнительные вопросы про подчеркивание на собеседовании
Какова роль подчеркивания в именовании объектов?
- При именовании в нижнем регистре
lower_case_with_underscores - При именовании в верхнем регистре
UPPER_CASE_WITH_UNDERSCORES
Некоторые имена, ограниченные символами подчеркивания, являются зарезервированными:
- С символом подчеркивания в начале имени не импортируется при общем импорте
from module import * - С двумя символами подчеркивания с обеих сторон имени считается системным, не рекомендуется использовать такие имена в других целях
- С двумя символами подчеркивания в начале имени считается приватным (не публичным) для класса
Какова роль отдельного символа подчеркивания?
$ python3 Python 3.6.8 (default, Feb 14 2019, 22:09:48) [GCC 7.4.0] on cygwin Type "help", "copyright", "credits" or "license" for more information. >>> _ Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '_' is not defined >>> 2 * 5 10 >>> _ 10 >>> _ = 1 >>> _ 1 >>> 2 * 5 10 >>> _ 1
Это связано с тем, что sys.stdout экранируется с помощью displayhook. Возьмем пример из официальной документации:
def displayhook(value): if value is None: return # Set '_' to None to avoid recursion builtins._ = None text = repr(value) try: sys.stdout.write(text) except UnicodeEncodeError: bytes = text.encode(sys.stdout.encoding, 'backslashreplace') if hasattr(sys.stdout, 'buffer'): sys.stdout.buffer.write(bytes) else: text = bytes.decode(sys.stdout.encoding, 'strict') sys.stdout.write(text) sys.stdout.write("\n") builtins._ = value
Кроме того единичное подчеркивание принято использовать для удобства интернализации.
ссылка на оригинал статьи https://habr.com/ru/post/459672/
Добавить комментарий