Объект кортежа подкласса Python с возможностью внутренней самореализации - PullRequest
1 голос
/ 29 ноября 2010

Я понимаю концепцию изменяемых и неизменяемых объектов в 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 ]

2 голосов
/ 29 ноября 2010

Если вам нужен изменяемый кортеж, используйте список.

edit:

Попробуйте это

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 голос
/ 29 ноября 2010

Довольно просто, все, что вам нужно сделать, это обернуть список.

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) и т. П.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...