Python子类元组对象具有在内部重新实现自我的能力

时间:2010-11-29 17:56:36

标签: python tuples mutable

我理解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引发?

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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)之类的方法来处理这些值。