Ways to make a class immutable in Python

与世无争的帅哥 提交于 2019-11-30 11:20:00
jsbueno

If the old trick of using __slots__ does not fit you, this, or some variant of thereof can do: simply write the __setattr__ method of your metaclass to be your guard. In this example, I prevent new attributes of being assigned, but allow modification of existing ones:

def immutable_meta(name, bases, dct):
    class Meta(type):
        def __init__(cls, name, bases, dct):
            type.__setattr__(cls,"attr",set(dct.keys()))
            type.__init__(cls, name, bases, dct)

        def __setattr__(cls, attr, value):
            if attr not in cls.attr:
                raise AttributeError ("Cannot assign attributes to this class")
            return type.__setattr__(cls, attr, value)
    return Meta(name, bases, dct)


class A:
    __metaclass__ = immutable_meta
    b = "test"

a = A()
a.c = 10 # this works
A.c = 20 # raises valueError
S.Lott

Don't waste time on immutable classes.

There are things you can do that are far, far simpler than messing around with trying to create an immutable object.

Here are five separate techniques. You can pick and choose from among them. Any one will work. Some combinations will work, also.

  1. Documentation. Actually, they won't forget this. Give them credit.

  2. Unit test. Mock your application objects with a simple mock that handles __setattr__ as an exception. Any change to the state of the object is a fail in the unit test. It's easy and doesn't require any elaborate programming.

  3. Override __setattr__ to raise an exception on every attempted write.

  4. collections.namedtuple. They're immutable out of the box.

  5. collections.Mapping. It's immutable, but you do need to implement a few methods to make it work.

If you don't mind reusing someone else's work:

http://packages.python.org/pysistence/

Immutable persistent (in the functional, not write to desk sense) data structures.

Even if you don't use them as is, the source code should provide some inspiration. Their expando class, for example, takes an object in it's constructor and returns an immutable version of it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!