@property speed overhead in Python

6k views Asked by At

I'm trying to understand the utility of the @property decorator in Python. Specifically, I set up a class using properties like so:

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

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, new_x):
        self._x = new_x

And I also set up a class without properties providing the same functionality:

class B(object):
    def __init__(self, x):
        self._x = x

I create an instance of each:

a = A(10)
b = B(10)

Running %timeit in iPython yields the following results

%timeit a.x
%timeit b._x

1000000 loops, best of 3: 213 ns per loop

10000000 loops, best of 3: 67.9 ns per loop

%timeit a.x = 15
%timeit b._x = 15

1000000 loops, best of 3: 257 ns per loop

10000000 loops, best of 3: 89.7 ns per loop

Clearly, the @property and @setter decorators are inferior if you're going to be talking to the object with significant frequency. My question is, simply, why use it? I would be interested to hear any use-cases for these decorators that people may have. Thanks.

2

There are 2 answers

0
Silas Ray On

The simple answer is you don't use propertys for basic attributes. They are useful for attributes that require additional logic when stored or retrieved. For example, attributes with values derived from other attributes or attributes that need error checking or other specialized filtering. Using propertys lets you use the common setter/getter pattern common in other languages in an ala carte, drop in fashion instead of forcing verbose boilerplate.

0
user2357112 On

If the attribute is so simple, don't use property. You don't need it. property is there for cases when getting and setting an attribute needs to do more, for example, if there's a computation involved:

@property
def area(self):
    return math.pi * self.radius**2

They're particularly useful for when something that used to be a simple __dict__ lookup suddenly needs to perform extra work. You can switch to a property without needing to add method call parentheses at every call site.