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

266 Views Asked by At

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?

1

There are 1 best solutions below

1
dsal3389 On BEST ANSWER

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