0

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 ?

2
  • Does this answer your question? `final` keyword equivalent for variables in Python? Commented Dec 16, 2022 at 3:56
  • @Alvi15 Note that the final decorator is only a type hint for your IDE. It won't stop people from actually modifying the attribute. Commented Dec 16, 2022 at 4:01

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

4 Comments

The problem is that a config object loaded from a YAML file often contains nested containers, which can still be freely mutated even through a class like above.
@blhsing It is possible to create immutable variants of those data structures if it is strictly necessary, but fair point.
@Selcuk Thanks, my question should be "how to create immutable dictionary". Simply use property of class should is not demand.
@SiuolLee That's not too hard, you should simply override __setitem__. See my updated answer for a trivial example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.