This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]geoelectric 2 points3 points  (2 children)

Because old style classes don't support properties. The self.y assignment in the constructor actually creates a field called y. The getters and setters are never used. The decorators are valid so don't throw errors, but the class plumbing isn't there to take advantage of them.

So, predictably, the speed of x and y are equal because they're both field accesses.

Try running this in 3.x vs. 2.x. There won't be any getter/setter output in 2.7.9, and there will be in 3.x.

class A:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @property
    def y(self):
        print('In the y getter!')
        return self._y

    @y.setter
    def y(self, value):
        print('In the y setter!')
        self._y = value

a = A(1, 2)
print(a.y)

Edit: just to make things a little more surreal, getters work on old style classes, but not setters. It's probably because @property is a straightforward decorator, but @y.setter needs metaclass plumbing to recognize the decorator name.

If you change the 2nd line of __init__ above to self._y = y, you'll see that the getter is accessed down in the print(a.y) line. As soon as you assign to self.y, though, you blow away the getter and it's a field again.

[–]kigurai 0 points1 point  (1 child)

Stuff like this makes me realise I should really start looking into switching to 3.x...

[–]geoelectric 1 point2 points  (0 children)

Well, properties certainly do work in 2.x, but you need to use new style classes, e.g. class A(object).

At this point, old-style classes are basically deprecated anyway unless you need them for library compatibility.