Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python @property versus method performance - which one to use?

I have written some code that uses attributes of an object:

class Foo:
    def __init__(self):
        self.bar = "baz"
myFoo = Foo()
print (myFoo.bar)

Now I want to do some fancy calculation to return bar. I could use @property to make methods act as the attribute bar, or I could refactor my code to use myFoo.bar().

Should I go back and add parens to all my bar accesses or use @property? Assume my code base is small now but due to entropy it will increase.

like image 520
Paul Tarjan Avatar asked Jul 17 '09 08:07

Paul Tarjan


3 Answers

If it's logically a property/attribute of the object, I'd say keep it as a property. If it's likely to become parametrised, by which I mean you may want to invoke myFoo.bar(someArgs) then bite the bullet now and make it a method.

Under most circumstances, performance is unlikely to be an issue.

like image 166
Vinay Sajip Avatar answered Nov 16 '22 13:11

Vinay Sajip


Wondering about performance is needless when it's so easy to measure it:

$ python -mtimeit -s'class X(object):
>   @property
>   def y(self): return 23
> x=X()' 'x.y'
1000000 loops, best of 3: 0.685 usec per loop
$ python -mtimeit -s'class X(object):

  def y(self): return 23
x=X()' 'x.y()'
1000000 loops, best of 3: 0.447 usec per loop
$ 

(on my slow laptop -- if you wonder why the 2nd case doesn't have secondary shell prompts, it's because I built it from the first with an up-arrow in bash, and that repeats the linebreak structure but not the prompts!-).

So unless you're in a case where you know 200+ nanoseconds or so will matter (a tight inner loop you're trying to optimize to the utmost), you can afford to use the property approach; if you do some computations to get the value, the 200+ nanoseconds will of course become a smaller fraction of the total time taken.

I do agree with other answers that if the computations become too heavy, or you may ever want parameters, etc, a method is preferable -- similarly, I'll add, if you ever need to stash the callable somewhere but only call it later, and other fancy functional programming tricks; but I wanted to make the performance point quantitatively, since timeit makes such measurements so easy!-)

like image 21
Alex Martelli Avatar answered Nov 16 '22 15:11

Alex Martelli


In cases like these, I find it much better to choose the option that makes the most sense. You won't get any noticeable performance loss with small differences like these. It's much more important that your code is easy to use and maintain.

As for choosing between using a method and a @property, it's a matter of taste, but since properties disguise themselves as simple attributes, nothing elaborate should be going on. A method indicates that it might be an expensive operation, and developers using your code will consider caching the value rather than fetching it again and again.

So again, don't go on performance, always consider maintainability vs. performance. Computers get faster and faster as time goes by. The same does not stand for the readability of code.

In short, if you want to get a simple calculated value, @property is an excellent choice; if you want an elaborate value calculated, a method indicates that better.

like image 7
Blixt Avatar answered Nov 16 '22 13:11

Blixt