Python子类元组对象能够在内部重新实例化自身

发布于 2024-10-05 18:50:32 字数 1906 浏览 0 评论 0原文

我理解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 引发的重复可以合并?

I understand the concept of mutable v. immutable objects in Python, no problem. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

李白 2024-10-12 18:50:32

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

编辑:

试试这个

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)

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)
苏佲洛 2024-10-12 18:50:32

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

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 不支持 私有成员

您可以通过直接从列表子类化来采取进一步措施来防止对 __values 的操作,但这需要更多工作,而且仍然可以使用 list.__setitem__(imListInstance, 0, 5 )等等。

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. One last advise, it's still possible to mess with self._values from the outside, that because Python doesn't support private members.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文