1

我理解 Python 中可变对象与不可变对象的概念,没问题。虽然任何不可变对象的内在价值都不能直接修改,但不可变对象的任何实例都可以用不同的值重新实例化。我想做的是在元组的子类上构建一个内部函数,该函数可以以受控的方式重新分配它自己的值。这可能是我似乎无法找到的基本功能,希望得到任何帮助。

例如,这是我想做的,但这显然行不通。

class myTuple(tuple):
    def __new__(self):
        initialValue = [1, 2, 3]
        return super(myTuple, self).__new__(self, initialValue)
    def resetMyself(self):
        newValue = [4, 5, 6]
        self = tuple(newValue)

结果如下...

>>> foo = myTuple()
>>> print foo
(1, 2, 3)
>>> foo.resetMyself()
>>> print foo
(4, 5, 6)

通过阅读本网站上对此类问题的大量回复,我知道你们中的一些人可能倾向于回答“为什么要这样做?” 但是让我们用更直接的答案来节省响应空间,如果真的是这样的话,可能包括“你不能这样做,没有办法”。

非常感谢大家!

编辑,感谢下面的答案,这是我最终得到的......

class semiImmutableList(list):
    def __setitem__(self, *args):
        raise TypeError("'semiImmutableList' object doesn't support item assignment")
    __setslice__ = __setitem__
    def __delitem__(self, *args):
        raise TypeError("'semiImmutableList' object doesn't support item deletion")
    __delslice__ = __delitem__
    def append(self, *args):
        raise AttributeError("'semiImmutableList' object has no attribute 'append'")
    def extend(self, *args):
        raise AttributeError("'semiImmutableList' object has no attribute 'extend'")
    def insert(self, *args):
        raise AttributeError("'semiImmutableList' object has no attribute 'insert'")
    def remove(self, *args):
        raise AttributeError("'semiImmutableList' object has no attribute 'remove'")
    def pop(self, *args):
        raise AttributeError("'semiImmutableList' object has no attribute 'pop'")
    def __init__(self):
        x = [1, 2, 3]
        super(semiImmutableList, self).__init__(x)
    def resetMyself(self):
        super(semiImmutableList,self).append(5)

您可以看到对上述内容的任何改进/调整,请发布。似乎可以组合 AttributeError raises 的重复?

4

2 回答 2

2

如果您想要一个可变元组,请使用列表。

编辑:

试试这个

class FrankenList(object):
    def __init__(self, init=None):
        self.__data = init or []

    def __getitem__(self, key):
        return self.__data[key]

    def __repr__(self):
        return repr(self.__data)

    def __str__(self):
        return str(self.__data)
于 2010-11-29T18:01:00.177 回答
1

很简单,你所要做的就是包装一个列表。

class ImmutableList(object):
    def __init__(self, *args):
        self.__values = args; # internally we store the values in a list

    # make imuList[0] = 2 raise an error, just like a tuple would
    def __setitem__(self, index, value):
        raise TypeError('ImmutableList does not support item assignment')

    # del imuList[0] should also raise
    def __delitem__(self, index, value):
        raise TypeError('ImmutableList does not support item deletion')**

    # make our imuList indexable, also catch the normal index error and raise one
    # that tells that this is an immutable list, will make it easier to debug :)
    def __getitem__(self, index):
        try:
            return self.__values[index]

        except IndexError:
            raise IndexError('ImmutableList index out of range')

    # the usual stuff
    def __repr__(self):
        return repr(self.__values)

    def __str__(self):
        return str(self.__values)

# create a new imulist
e = ImmutableList(1, 2, 3, 4)

# works!
print e[0]

# raises an error
e[0] = 5

# raises another error
print e[9]

现在您所要做的就是self._values在类内部进行修改。最后一个建议,仍然有可能self._values从外部搞乱,因为 Python 不支持private members

您可以通过直接从列表中继承子类来采取进一步措施来防止操作,但这是更多的工作,人们仍然可以通过使用等__values来摆弄这些值。list.__setitem__(imListInstance, 0, 5)

于 2010-11-29T18:32:54.030 回答