Search code examples
pythonvariablesreadonly

Could I set a variable readonly in Python?


I want to set a object in module be readonly and shared in common. Like follow situation:

# configure.py
with open("config.yaml","r") as f:
    config = yaml.load(f)

and configure.py will be used by other scripts. The config object shoud be readonly and fixed.

# data.py
from configure import config
some_operation( config )
# ....
# main.py
from configure import config
config["attr"] = "erroneously_setting"
some_operation( config )

I worry that config object would be erroneously modified by other scripts.

Could I set a variable readonly ?


Solution

  • No, you can't make an attribute read-only in Python, but you can hide the implementation details and use properties to expose attributes:

    class Config:
        def __init__(self):
            self._foo = 1
    
        @property
        def foo(self):
            return self._foo
    
    
    if __name__ == '__main__':
        config = Config()
        print("Foo is", config.foo)
        config.foo = 1
    

    this will print

    Foo is 1
    

    then

    Traceback (most recent call last):
      File "test.py", line 13, in <module>
        config.foo = 1
    AttributeError: can't set attribute 'foo'
    

    Edit: Here is an example of an immutable dictionary per OP's clarification:

    class ImmutableDict(dict):
        def set(self):
            raise NotImplemented()
    
        def __setitem__(self, *args, **kwargs):
            raise RuntimeError("This is an immutable dictionary")
    
    
    if __name__ == '__main__':
        my_dict = ImmutableDict({"foo": 1, "bar": 2})
        print(my_dict["foo"])
        my_dict["foo"] = 3
    

    This should print:

    1
    

    then

    Traceback (most recent call last):
        my_dict["foo"] = 3
        raise RuntimeError("This is an immutable dictionary")
    RuntimeError: This is an immutable dictionary