Почему у Python нет истинных констант? Разве это не опасно?

Python 3

Я изучаю Python через книгу. Прямо сейчас я узнал, что у Python нет констант в том смысле, в котором они доступны на С++ или С#... Например, можно написать такой код опасности:

>>> import math
>>> math.pi
3.141592653589793
>>> math.pi = 123.456
>>> math.pi
123.456
>>> 

Хм... Это неприятный сюрприз для меня...

т.е. потенциально я не защищен от того, что любой модуль (который не мой), который я загружаю в свой код, может повредить данные, которые не будут меняться.

Почему в Python это сделано? Разве это не опасно?

Ответы

Ответ 1

Python - динамический язык: вы можете добавлять/удалять/изменять атрибуты и функции объектов, чтобы они соответствовали вашим потребностям. Хотя это немного полужирный, в основном объект является не чем иным, как словарем. Вы можете просто добавить атрибуты к одному объекту и т.д. Python также поддерживает - более или менее - идею утиная печать:

"Если это выглядит как утка и шарлатанцы, как утка, это утка".

Другими словами, если вы хотите, чтобы объект выглядел как другой объект, ожидаемый определенной функцией, просто дайте ему перья и ноги и удалите его вторую голову, и функция примет его.

Это один из принципов проектирования Python, и это может быть очень полезно: скажем, вы хотите исправлять функцию в фрагменте кода, который вы можете просто:

def better_function(param,eter):
    #...
    pass

somemodule.badfunction = better_function

и тем самым исправить код. Кроме того, если есть пакет, который, например, делает некоторые приятные вещи с веб-страницами, вы можете легко изменить его, чтобы делать что-то с помощью принтеров, переписав несколько методов.

Недостатком является то, что у вас меньше контроля над модулями, которые будут вводить ошибки (специально, я не утверждаю, что они это делают, хотя нельзя исключать злонамеренные намерения). Есть несколько способов защитить ваш код, например, сделать классы и объекты неизменяемыми: вы можете перезаписать __setattr__ и __delattr__, которые вызываются для установки и удаления атрибута и, таким образом, затрудняют/не могут изменить объект, но это разрушит динамизм Python: программисты на Python ожидают, что они могут изменить объект.

Тяжелая защита объектов/классов/... однако противоречит принципам динамического языка. Если вам нужен язык, который гарантирует такие вещи, вам лучше использовать статически типизированный язык, например .

Ответ 2

Python - это особый язык программирования, поскольку он сильно зависит от вашей гигиены работы, а не от встроенных механизмов. Если вы хотите поддерживать большой проект python, вы не можете обойтись без модульных тестов, проверки кода и т.д., Но опять же, вам это нужно в любой другой технологии.

Как только вы просмотрите код, вам действительно не нужны константы, потому что даже самые неопытные рецензенты заметят, что вы меняете math.pi или что-то с именем IN_THIS_CONVENTION и, возможно, это не очень хорошая идея.

Ответ 3

Кроме того.

для предотвращения ошибок вы можете использовать такой код в классе

class C:
    def __init__(self):
        self.__a = 0

    @property
    def a(self):
        return self.__a

    @a.setter
    def a(self, new_value):
        raise Exception('YOU CAN NOT MODIFY A')

c = C()
# print(c.__a) # can not access to __a
print(c.a)
# c.a = 2 # can not set new value for __a via c.a

но в этой форме вы также можете изменить __a через

c._C__a = 2
print(c.a)

Я думаю, этого достаточно для предотвращения ошибок.