在Python中使类不可变的方法

2024-05-14 23:05:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做一些分布式计算,其中几个机器在假设它们都有不同类的相同版本的情况下进行通信。因此,使这些类不可变似乎是一个好的设计;不是说它必须挫败一个怀有恶意的用户,只是不可变到永远不会被意外修改。

我该怎么办?例如,我如何实现一个元类,使在定义之后使用它的类是不可变的?

>>> class A(object):
...     __metaclass__ = ImmutableMetaclass
>>> A.something = SomethingElse # Don't want this
>>> a = A()
>>> a.something = Whatever # obviously, this is still perfectly fine.

替代方法也可以,例如采用类并返回不可变类的decorator/函数。


Tags: 用户版本机器定义object情况thissomething
3条回答

不要在不可变的类上浪费时间。

有些事情你可以做的远比创建一个不可变的对象要简单得多。

这里有五种不同的技巧。你可以从中挑选。任何人都可以工作。一些组合也会起作用。

  1. 文件。事实上,他们不会忘记的。给他们荣誉。

  2. 单元测试。使用一个简单的模拟来模拟应用程序对象,该模拟将^{}作为异常处理。对对象状态的任何更改都是单元测试中的失败。它很简单,不需要任何精心的编程。

  3. 重写__setattr__以在每次尝试写入时引发异常。

  4. ^{}。它们是不可变的。

  5. ^{}。它是不可变的,但您确实需要实现一些方法才能使其工作。

如果使用^{}的旧技巧不适合您,则此技巧或其某些变体可以: 只需编写元类的^{}方法来保护您。在本例中,我防止分配新属性,但允许修改现有属性:

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

如果你不介意重复别人的工作:

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

不可变的持久性(在函数中,不是写到桌面的)数据结构。

即使您不按原样使用它们,源代码也应该提供一些灵感。例如,他们的expando类在其构造函数中接受一个对象并返回其不可变版本。

相关问题 更多 >

    热门问题