Python игнорирует сеттер
Я новичок в Python, и я пытаюсь создать класс с get / set в качестве свойства. Я скопировал простой пример из интернета, и кажется, что Python игнорирует мой установщик. Я делаю что-то очень глупое, потому что я не понимаю, почему это не работает.
Я использую Python 2.6.6 в Linux.
Спасибо
#!/usr/bin/python
class Celsius:
def __init__(self, temperature = 0):
self._temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
@property
def temperature(self):
print("Getting value")
return self._temperature
@temperature.setter
def temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self._temperature = value
c = Celsius()
c.temperature = -5555
print c.temperature
Единственное, что у меня есть в командной строке, это то, что она печатает -5555. Это полностью игнорирует мой сеттер.
Это сводит меня с ума, есть идеи?
1 ответ
Проблема в том, что вы определили Celsius
как класс старого стиля.
Документация для property
делает это довольно ясно:
Возврат атрибута свойства для классов нового стиля (классов, производных от
object
).
Причина этого в том, что @property
работает, создавая дескриптор, и, как говорят в документах по классам нового стиля:
Основной мотивацией для введения классов нового стиля является предоставление единой объектной модели с полной метамоделью. Он также имеет ряд практических преимуществ, таких как возможность создавать подклассы для большинства встроенных типов или введение "дескрипторов", которые обеспечивают вычисляемые свойства.
Чтобы это исправить, просто сделайте Celsius
класс нового стиля, наследуя от object
:
class Celsius(object):
# all the rest of your code is the same.
Конечно, если вы обновитесь до Python 3, проблема исчезнет, потому что все классы - это классы нового стиля. В частности, если вы не укажете другие базовые классы, вы получите object
в качестве базового класса, 1 так class Spam:
, class Spam():
, а также class Spam(object):
все означают то же самое в 3.x, что class Spam(object):
подразумевается в 2.x.
1. Это на самом деле два изменения под прикрытием. Во-первых, class
Statement всегда компилируется в вызов метакласса, а не в специальную конструкцию класса старого стиля. Во-вторых, метакласс по умолчанию, type
, заполняет (object,)
если вы передадите ему пустой список баз. Но вам редко нужно понимать что-либо из этого, поэтому в сноске болит зрение.