Search code examples
pythonpropertiespython-decoratorsreadonly-attribute

Convert Instance Fields into Properties


I would like to convert all instance fields of an object into properties (getter only) in order to make them read only. The fields might be defined by a subclass.

How can I achieve this?

class SomeClass(object):

    def __init__(self, foo, bar):

        self.foo = foo
        self.bar = bar

        convert_all_instance_fields_into_properties(self)   # implementation ?

Solution

  • It is possible to achieve readonly fields using python builtins quite easily:

    class X:
    
        def __init__(self, val):
            self.foo = val
    
        def __setattr__(self, key, value):
            if not hasattr(self, key):  # only for first set
                super(X, self).__setattr__(key, value)
            else:
                raise ValueError
    
    
    def main():
        x = X('bar')
        y = X('baz')
    
        assert x.foo == 'bar'
        assert y.foo == 'baz'
    
        # raises ValueError
        x.foo = 'Raise an error!'
    

    If you want to specify which fields are readonly

    class X:
    
        readonly = ['foo']
    
        def __init__(self, val):
            self.foo = val
    
        def __setattr__(self, key, value):
            if key in self.readonly and not hasattr(self, key):
                super(X, self).__setattr__(key, value)
            else:
                raise ValueError