Search code examples
pythonpython-3.xpropertiesreadonly-attribute

How do I make all instance variables of a class readonly?


Let's say I have a class like the following:

class Test:
    def __init__(self, some_data_source):
        self.a = 5
        self.b = some_data_source['c']

I want to make all instance variables of this class read-only and will use it as follows:

data_source = {
    'c': 'some data'
}

x = Test(data_source)

# Should be illegal i.e result in an exception
x.a = 5
x.b = None

# This should be legal
print(x.a)

Initially, I thought about using properties, but then I realized that in order to add them dynamically, I would need to add these attributes after the class is defined (e.g Test.attribute = property(...)). This doesn't work because I want to define these properties inside the class (specifically in __init__).

How else can I make all of my instance variables read-only for a class?


Solution

  • check with hasattr if the variable is exists and if it is raise error that you can't set new value to this variable and check it in __setattr__

    class Test:
        def __init__(self, some_data_source):
            self.a = 5
            self.b = some_data_source['c']
    
        def __setattr__(self, name, value):
            if hasattr(self, name):
                raise ValueError('cannot set %s to %s' %(value, name))
            self.__dict__[name]=value
    
    
    data_source = {
        'c': 'some data'
    }
    
    x = Test(data_source)
    x.b='raise' # this will raise error