Issue
I am new to python and I try to create a class with get/set as property. I have copied a simple example from internet and it seems that Python ignores my setter. Am I doing something very stupid because I don't understand why it does not work.
I am running python 2.6.6 on Linux.
Thanks
#!/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
The only thing I have in the command line is that it print -5555. It completely ignores my setter.
This is driving me crazy, any ideas?
Solution
The problem is that you've defined Celsius
as an old-style class.
The documentation for property
makes this pretty clear:
Return a property attribute for new-style classes (classes that derive from
object
).
The reason for this is that @property
works by building a descriptor, and, as the docs on new-style classes say:
The major motivation for introducing new-style classes is to provide a unified object model with a full meta-model. It also has a number of practical benefits, like the ability to subclass most built-in types, or the introduction of “descriptors”, which enable computed properties.
To fix this, just make Celsius
a new-style class, by inheriting from object
:
class Celsius(object):
# all the rest of your code is the same.
Of course if you upgrade to Python 3, the problem goes away, because all classes are new-style classes. In particular, if you don't specify any other base classes, you get object
as a base class,1 so class Spam:
, class Spam():
, and class Spam(object):
all mean the same thing in 3.x that class Spam(object):
meant in 2.x.
1. This is actually two changes under the covers. First, the class
statement always compiles to a call to a metaclass, never to the special old-style class construction. Second, the default metaclass, type
, fills in (object,)
if you pass it an empty list of bases. But you rarely need to understand any of this stuff, which is why it's in a footnote that hurts your eyes to squint at.
Answered By - abarnert
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.