2

This is probably trivial, but I got not resolution when searching for this:

I have the following simple class:

class Celcius:
    def __init__(self, temperature=0):
        self.temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature*1.8) + 32

    def get_temperature(self):
        print "getting temp"
        return self._temperature

    def set_temperature(self, value):
        if value < -273:
            raise ValueError("dayum u trippin' fool")
        print "setting temp"
        self._temperature = value

    temperature = property(get_temperature, set_temperature)

c = Celcius()

When I run this in Sublime Text 3 (by hitting cmd+B) the console does not print anything. I should see:

setting temp

If I add the following to the end of the script:

print "banana"
print "apple"

both lines are printed as expected.

If I run the above python script from the terminal (with python -u, or just python), the result is exactly the same. I assume I am missing something very stupid. Thank you

luffe
  • 1,588
  • 3
  • 21
  • 32

2 Answers2

14

This does not work because you wrote

class Celcius:
    ...

while using features of new-style classes. To use properties, you need to inherit from object:

class Celcius(object):
    ...

does the trick.

Reference: Descriptor Howto, quote: Note that descriptors are only invoked for new style objects or classes (a class is new style if it inherits from object or type)

Bluehorn
  • 2,956
  • 2
  • 22
  • 29
  • Ah, that worked! Thank you. So I should always inherent from `object` just to be safe? – luffe May 20 '15 at 10:58
  • 1
    @luffe: Read about ["new-style class"](https://docs.python.org/2/glossary.html#term-new-style-class) in the glossary. In Python 3 you always have new-style classes, so your code will run there without modifications. – Matthias May 20 '15 at 11:05
-1

You are not calling the set_temperature(self, value) method at all.

This line

self.temperature = temperature

in your __init__() method (which is called by the c = Celcius()) just sets the self.temperature directly, without calling the setter.

The obvious solution is to rewrite your init() method from:

def __init__(self, temperature=0):
    self.temperature = temperature

to:

def __init__(self, temperature=0):
    self.set_temperature(temperature)
geckon
  • 8,316
  • 4
  • 35
  • 59
  • But if I run the above code (with parenthesis around the print statement) on www.repl.it's Python 3 interpreter, it prints "setting temp"...? – luffe May 20 '15 at 10:56
  • 2
    There is a `temperature` *property*, it calls `set_temperature` when assigning to it. – Martijn Pieters May 20 '15 at 10:59
  • You are right, I know about properties but I missed that line. Thank you. – geckon May 20 '15 at 10:59
  • 1
    @luffe: In Python 3 it will use the property because the so called "new style classes" are default there. In Python 2 you have to make `object` the base class. – Matthias May 20 '15 at 11:00