Setting a class attribute of the type dict as private in python

Question:

I have the following situation (here a bit simplified):

class MyClass():
    tables = dict
    matrices = dict

    def __init__(self, table_A, table_B=None, A=None, B=None)
        self.tables = {'A': table_A, 'B': table_B}
        self.matrices = {'A': A, 'B': B}

Now do not want my matrices to able to be set manually. Therefore my approach was to simply set them protected.

class MyClass():
    tables = dict
    _matrices = dict

    def __init__(self, table_A, table_B=None, A=None, B=None)
        self.tables = {'A': table_A, 'B': table_B}
        self._matrices = {'A': A, 'B': B}

    @property
        def matrices(self):
            # Getter function of the matrices attribute.
            return self._matrices

    @matrices.setter
    def matrices(self, value):
        raise AttributeError('The matrices of the model cannot be set manually!')

If I now initalize an instance myclass of the MyClass class it results in the following situation:
myclass.matrices = 3 (raises my AttributeError from the setter method – this is what I want)
myclass.matrices['A'] = 3 (no warning, just does what I wrote – I would like to avoid this!)

What should I do in a situation like this in your opinion?

I already thought of two workarounds:

  1. extend my number of attributes, have single attributes for each former dict entry (_matrix_A, _matrix_B) and loose the advantage of the
    stucture given by the dict.

  2. write an additional class MatrixClass and amending my base class MyClass

         _A = np.Array
         _B = np.Array
    
         def __init__(self, A, B):
             self._A = A
             self._B = B
    
         @property
         def A(self):
             # Getter function of the A attribute.
             return self._A
    
         @A.setter
         def A(self, dictionary):
             raise AttributeError('The matrix A cannot be set manually.')
    
     class MyClass():
         tables = dict
         _matrices = MatrixClass
    
         def __init__(self, table_A, table_B=None, A=None, B=None)
             self.tables = {'A': table_A, 'B': table_B}
             self._matrices = MatrixClass(A, B)
    
         @property
             def matrices(self):
                 # Getter function of the matrices attribute.
                 return self._matrices
    
         @matrices.setter
         def matrices(self, value):
             raise AttributeError('The matrices of the model cannot be set manually!')```
    
    
    

What would you recommend to be a kind of pretty solution to this?
Thank you!

Asked By: ghtzusido

||

Answers:

You could use the library frozendict which provides a immutable dictionnary. I would have done something like this :

pip install frozendict
from frozendict import frozendict

class MyClass():

    def __init__(self, A=None, B=None):
        self._matrices = frozendict({'A': A, 'B': B})

    @property
    def matrices(self):
        # Getter function of the matrices attribute.
        return self._matrices

    @matrices.setter
    def matrices(self, value):
        raise AttributeError('The matrices of the model cannot be set manually!')

Then, if I try to change the value of key A in matrices, like :

c = MyClass()
c.matrices["A"] = 2

… an error will be raised:

TypeError: 'frozendict' object doesn't support item assignment
Answered By: thomask
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.