Каков наилучший способ / практика для обеспечения того, чтобы словарь, передаваемый в качестве аргумента в конструктор другого класса, не подвергался мутации? - PullRequest
0 голосов
/ 01 ноября 2018

Предположим, есть 2 модуля Python - библиотека и приложение.

Код библиотеки:

class lib():

    def __init__(self,arg):
        smallArg = arg['key1']['key2']
        smallArg['key3'] = 2

Код приложения:

class app():

    def __init__(self):
        self.arg = {'key1' : {'key2' : {'key3' : 1}}}
        self.libObj = lib(self.arg)

    def getArg(self):
        print(self.arg)

appObj = app()
app.getArg()

, так как словари являются изменяемыми, печатается словарь {'key1': {'key2': {'key3': 2}}}, который был изменен кодом библиотеки. Это означает, что библиотека может даже добавить больше ключей или удалить их, и приложение также получит этот мутированный словарь.

Есть ли способ / практика, чтобы действительно гарантировать, что другие модули не нарушают структуру передаваемого словаря ??

---> использование copy.deepcopy () или json.loads (json.dumps ()) не кажется правильным. Должен быть лучший способ!

Это лишь небольшой пример, когда 2 модуля взаимодействуют друг с другом. Подумайте еще о нескольких модулях, которые передают друг другу вложенные словари, вычисляют их и возвращают. Любой модуль может изменить структуру вложенного словаря. Существует большая вероятность пропустить эту деталь и может нарушить код.

Есть ли лучший способ? Должно быть.

1 Ответ

0 голосов
/ 01 ноября 2018

В Python нет аналога частных или защищенных данных, которые пытаются предоставить некоторые другие языки. Чтобы действительно сохранить оригинал, copy.deepcopy будет лучшим выбором, и вы просто заплатите цену за копирование данных в память.

Для поверхностной карты ключей / значений вы можете избежать копирования, передав прокси-сервер для сопоставления:

>>> from types import MappingProxyType
>>> d = {'k': 'v'}
>>> d_readonly = MappingProxyType(d)
>>> d_readonly['k']
'v'
>>> d_readonly['k'] = 'spam'
TypeError: 'mappingproxy' object does not support item assignment

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

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

  • Избегайте изменения входных данных и возвращайте новый объект (например, sorted) или
  • Изменить ввод на месте и ничего не возвращать (например, list.sort)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...