Olezhka
А какой смысл этих констант? Это чтобы по забывчивости не изменить случайно какое-то важное значение в программе, которое менять нельзя?
Главный их смысл в том, что они быстрее обрабатываются. В питоне их нет, но это не проблема ни для кого. Люди всегда помнят, где у них константы, для этого достаточно их просто обозначить большими буквами. Например, в tkinter ты их видишь в виде LEFT, BOTH и так далее. Вот большие буквы это и значат, что это какие-то константы, которые имеют фиксированное значение. При этом их можно поменять так же прекрасно, потому что в питоне нет констант.
>>> import tkinter.constants
>>>
>>> dir(tkinter.constants)
['ACTIVE', 'ALL', 'ANCHOR', 'ARC', 'BASELINE', 'BEVEL', 'BOTH', 'BOTTOM', 'BROWSE', 'BUTT', 'CASCADE', 'CENTER', 'CHAR', 'CHECKBUTTON', 'CHORD', 'COMMAND', 'CURRENT', 'DISABLED', 'DOTBOX', 'E', 'END', 'EW', 'EXTENDED', 'FALSE', 'FIRST', 'FLAT', 'GROOVE', 'HIDDEN', 'HORIZONTAL', 'INSERT', 'INSIDE', 'LAST', 'LEFT', 'MITER', 'MOVETO', 'MULTIPLE', 'N', 'NE', 'NO', 'NONE', 'NORMAL', 'NS', 'NSEW', 'NUMERIC', 'NW', 'OFF', 'ON', 'OUTSIDE', 'PAGES', 'PIESLICE', 'PROJECTING', 'RADIOBUTTON', 'RAISED', 'RIDGE', 'RIGHT', 'ROUND', 'S', 'SCROLL', 'SE', 'SEL', 'SEL_FIRST', 'SEL_LAST', 'SEPARATOR', 'SINGLE', 'SOLID', 'SUNKEN', 'SW', 'TOP', 'TRUE', 'UNDERLINE', 'UNITS', 'VERTICAL', 'W', 'WORD', 'X', 'Y', 'YES', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
>>>
>>> tkinter.constants.LEFT
'left'
>>> tkinter.constants.YES
1
>>>
В других языках, где есть константы в виде синтаксических конструкций языка, эти константы не только запускают оптимизацию в отношении себя, потому что константы требуют меньше операций (они только читаются, а писать их не надо, поэтому вокруг них и нет этой обвязки писательской), но и также проясняют написанный код. Когда ты видишь определённую функцию или только сигнатуру этой функции, в которой принимаемые аргументы какие-то константные, а какие-то переменные, то ты лучше понимаешь, как эту функцию вызывать можно, а как её вызывать нельзя, что в неё можно передать, а что в неё нельзя передавать. Например, если функция принимает только один константный массив, то ты уже заранее знаешь, что если ты передашь в неё любой массив, то функция его не поменяет, а просто будет читать его только. Но если функция принимает только один переменный массив (неконстантный), то ты уже заранее знаешь, что если ты передашь в неё любой массив, то функция его может запросто поменять, поэтому надо дополнительно учесть этот момент, чтобы ты потом не столкнулся с какими-то неожиданными изменениями в массиве, которые тебе не были нужны.
То есть у тебя больше контроля над кодом. Ты пометил какую-то хрень константной и не переживаешь больше за неё. Даже если она потом будет передана функции, которая принимает переменный аргумент и может поменять его, то у тебя компилятор выдаст ошибку в стиле “вы подаёте константную хрень в функцию на месте неконстантного аргумента, обратите внимание, что так делать нельзя”. И ты такой “о! точно! это я вот не подумал! надо исправить код!”. Вот так это работает.