简体   繁体   English

Python子类元组对象具有内部实例化自身的能力

[英]Python subclass tuple object with ability to reinstantiate self internally

I understand the concept of mutable v. immutable objects in Python, no problem. 我了解Python中可变v。不可变对象的概念,没问题。 While any immutable object's intrinsic value cannot be modified directly, any instance of an immutable object can be reinstantiated with different values. 尽管不能直接修改任何不可变对象的固有值,但是可以使用不同的值重新实例化不可变对象的任何实例。 What I would like to do is build an internal function on a subclass of tuple that can in a controlled fashion, reassign it's own value. 我想做的是在元组的子类上构建内部函数,该子类可以以受控方式重新分配其自身的价值。 This could be basic functionality that I just can't seem to find and would appreciate any assistance. 这可能是我似乎找不到的基本功能,将不胜感激。

For example, here is what I'd like to be able to do, but this obviously doesn't work. 例如,这是我想做的事情,但这显然行不通。

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)

With the following results... 结果如下...

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

From reading a larger number of responses to questions like this on this site, I know some of you may have the tendency to respond with "Why would you want to do this?" 通过阅读本网站上对此类问题的大量答复,我知道你们中的某些人可能会倾向于“为什么要这样做?” but let's save the response space with more direct answers, including possibly "You cannot do that no way, no how," if that's really the case. 但是,让我们通过更直接的答案来节省响应空间,包括如果确实是这样的话,可能包括“您不能那样做,不能怎么做”。

Thanks very much all! 非常感谢大家!

EDIT, THANKS FOR THE ANSWER BELOW, HERE IS WHAT I ENDED UP WITH... 编辑,感谢下面的答案,这就是我最后得到的...

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)

Any improvements/adjustments to the above that you can see please post. 您可以看到对上述内容的任何改进/调整。 Seems like the duplication of AttributeError raises could be combined? 好像重复的AttributeError加注可以合并吗?

If you want a mutable tuple, use a list. 如果您想要一个可变的元组,请使用一个列表。

edit: 编辑:

try this 尝试这个

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)

Pretty easy, all you have to do is to wrap a list. 非常简单,您要做的就是包装一个列表。

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]

Now all you have to do is to modify self._values inside the class. 现在您要做的就是在类中修改self._values One last advise, it's still possible to mess with self._values from the outside, that because Python doesn't support private members . 最后一个建议是,仍然可能从外部弄乱self._values ,因为Python不支持private成员

You can take further measures against the manipulation of __values by subclassing from list directly, but that's more work and one can still fiddle around with the values by using list.__setitem__(imListInstance, 0, 5) and the like. 您可以通过直接从list进行子类化来进一步采取措施来防止__values的操纵,但这是更多的工作,并且仍然可以通过使用list.__setitem__(imListInstance, 0, 5)等来摆弄这些值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM