Подтвердить что ты не робот

Почему Python решил отказаться от постоянных ссылок?

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

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

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

Любые идеи будут оценены.


Хотя ответы полезны, я не видел ни одной причины, почему const был бы сложно реализовать или неработать в Python. Я думаю, что "не-Pythonic" также будет считаться веской причиной, но действительно ли это? Python выполняет скремблирование переменных частного экземпляра (начиная с __), чтобы избежать случайных ошибок, а const, похоже, не отличается от духа.


EDIT: Я просто предложил очень скромную щедрость. Я ищу немного подробней о том, почему Python закончил без const. Я подозреваю, что причина в том, что его действительно сложно реализовать, чтобы работать отлично; Я хотел бы понять, почему это так сложно.

4b9b3361

Ответ 1

В PEP 351 Барри Варшава предложила протокол для "замораживания" любой изменяемой структуры данных, аналогично тому, как frozenset делает непреложный набор. Замороженные структуры данных могут быть хешируемыми и поэтому способны использоваться как ключи в словарях.

Предложение было обсуждено на python-dev, с критика Раймонда Хеттингера наиболее подробно.

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

Ответ 2

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

Используйте дескрипторы get-only и четко указывайте в своей документации, что эти данные предназначены только для чтения. В конце концов, определенный кодер, возможно, найдет способ использовать ваш код по-разному, о чем вы думали.

Ответ 3

Есть много вопросов дизайна о любом языке, ответ на большинство из которых "просто потому, что". Довольно ясно, что такие константы противоречат идеологии Python.


Вы можете создать атрибут класса только для чтения, используя . Это не тривиально, но это не очень сложно. Способ его работы заключается в том, что вы можете создавать свойства (объекты, которые выглядят как атрибуты, но вызов метода при доступе) с помощью декоратора property; если вы создадите getter, но не свойство setter, вы получите атрибут только для чтения. Причиной программирования метакласса является то, что, поскольку __init__ получает полностью сформированный экземпляр класса, вы фактически не можете установить атрибуты на то, что вы хотите на этом этапе! Вместо этого вы должны установить их при создании класса, что означает, что вам нужен метакласс.

Код из этот рецепт:

# simple read only attributes with meta-class programming

# method factory for an attribute get method
def getmethod(attrname):
    def _getmethod(self):
        return self.__readonly__[attrname]

    return _getmethod

class metaClass(type):
    def __new__(cls,classname,bases,classdict):
        readonly = classdict.get('__readonly__',{})
        for name,default in readonly.items():
            classdict[name] = property(getmethod(name))

        return type.__new__(cls,classname,bases,classdict)

class ROClass(object):
    __metaclass__ = metaClass
    __readonly__ = {'a':1,'b':'text'}


if __name__ == '__main__':
    def test1():
        t = ROClass()
        print t.a
        print t.b

    def test2():
        t = ROClass()
        t.a = 2

    test1()

Ответ 4

В то время как один программист, написавший код, является согласным взрослым, два программиста, работающие на одном и том же коде, редко соглашаются с взрослыми. Более того, если они не ценят красоту кода, но их сроки или исследовательские фонды.

Для таких взрослых существует определенная безопасность, предоставляемая Enthought Traits.

Вы можете посмотреть в Constant и ReadOnly черты.

Ответ 5

Для некоторых дополнительных мыслей здесь возникает аналогичный вопрос о Java:
Почему в Java нет постоянной функции?

Когда вы спрашиваете, почему Python решил отказаться от постоянных ссылок, я думаю, что полезно подумать о том, как они будут реализованы на этом языке. Должен ли Python иметь какое-то специальное объявление, const, создавать ссылки на переменные, которые нельзя изменить? Почему бы не позволить объявлять переменные float/int/what then then, они наверняка помогут предотвратить ошибки программирования. Пока мы это делаем, добавляем модификаторы класса и метода, такие как protected/private/public/etc. поможет принудительно выполнить проверку типа компиляции против незаконного использования этих классов.... довольно скоро мы потеряли красоту, простоту и элегантность, которые являются Python, и мы пишем код в виде какого-то ублюдкового ребенка С++/Java.

В настоящее время Python передает все по ссылке. Это будет своего рода специальная модификация pass-by-reference-but-flag-it-to-prevent... довольно частный случай (и, как указывает Tao of Python, просто "не-Pythonic" ).

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