Хотя мне это никогда не было нужно, меня просто поразило, что создание неизменяемого объекта в Python может быть немного сложнее.Вы не можете просто переопределить __setattr__
, потому что тогда вы даже не можете установить атрибуты в __init__
.Подклассы кортежа - это хитрость, которая работает:
class Immutable(tuple):
def __new__(cls, a, b):
return tuple.__new__(cls, (a, b))
@property
def a(self):
return self[0]
@property
def b(self):
return self[1]
def __str__(self):
return "<Immutable {0}, {1}>".format(self.a, self.b)
def __setattr__(self, *ignored):
raise NotImplementedError
def __delattr__(self, *ignored):
raise NotImplementedError
Но тогда у вас есть доступ к переменным a
и b
через self[0]
и self[1]
, что раздражает.
Возможно ли это в Pure Python?Если нет, то как мне это сделать с расширением C?
(ответы, которые работают только в Python 3, являются приемлемыми).
Обновление:
Таким образом, кортеж подклассов - это способ сделать это в Pure Python, который работает хорошо, за исключением дополнительной возможности доступа к данным с помощью [0]
, [1]
и т. Д. Итак, для завершения этого вопроса все, что не хватает, так это как это сделать«правильно» в C, что, я подозреваю, было бы довольно просто, просто не реализовав geititem
или setattribute
и т. д. Но вместо того, чтобы делать это самому, я предлагаю вознаграждение за это, потому что я ленивый.:)