Python @property vs方法性能 - 使用哪一个?

时间:2009-07-17 08:58:40

标签: python performance properties

我编写了一些使用对象属性的代码:

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

现在我想做一些花哨的计算来返回bar。我可以使用@property将方法作为属性bar,或者我可以重构我的代码以使用myFoo.bar()

我应该返回并为所有bar次访问添加parens还是使用@property?假设我的代码库现在很小,但由于熵会增加。

6 个答案:

答案 0 :(得分:21)

如果它在逻辑上是对象的属性/属性,我会说它保留为属性。如果它可能变得参数化,我的意思是你可能想要调用myFoo.bar(someArgs)然后咬住子弹并使它成为一种方法。

在大多数情况下,性能不太可能成为问题。

答案 1 :(得分:19)

当它很容易衡量时,对性能的了解是不必要的:

$ 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
$ 

(在我的慢速笔记本电脑上 - 如果你想知道为什么第二个案例没有辅助shell提示,那是因为我是从第一个用bash中的向上箭头构建的,并且重复了换行结构而不是提示! - 。)

因此,除非你知道200+纳秒左右的情况(重要的内环,你试图最大限度地优化),你可以负担得起使用属性方法;如果你做一些计算来得到这个值,那么200+纳秒当然会占总时间的一小部分。

我同意其他答案,如果计算变得太重,或者你可能想要参数等,一种方法更可取 - 同样,我会补充说,如果你需要在某处隐藏可调用的但只有稍后再称它,以及其他花哨的函数式编程技巧;但我想定量地提高性能,因为timeit使得这样的测量变得如此简单! - )

答案 2 :(得分:7)

在这样的情况下,我发现选择最有意义的选项要好得多。如果存在这些差异,您将不会获得任何明显的性能损失。您的代码易于使用和维护更为重要。

至于在使用方法和@property之间进行选择,这是一个品味问题,但由于属性将自己伪装成简单的属性,因此不应该进行任何详细的讨论。一种方法表明它可能是一项昂贵的操作,使用您的代码的开发人员会考虑缓存该值而不是一次又一次地获取它。

再次,不要继续表现,始终考虑可维护性与性能。随着时间的推移,计算机变得越来越快。这同样不代表代码的可读性。

简而言之,如果您想获得一个简单的计算值,@property是一个很好的选择;如果你想要计算精细的值,方法表明更好。

答案 3 :(得分:3)

我会去重构,但只是为了风格问题 - 对我来说似乎更清楚的是“花哨的计算”可能会持续进行方法调用,而我希望某个属性几乎是无操作的,但这是一个品味问题。

不要担心装饰者的表现......如果你认为它可能是一个问题,请在两种情况下测量性能,看看它添加多少(我的猜测是,如果相比它会完全忽略不计)你花哨的计算)。

答案 4 :(得分:2)

我同意大多数人的观点,几年前我在Python中建立水文模型时做了很多测量,发现使用@property的速度完全完全的计算结果黯然失色。

例如,创建方法局部变量(在我的计算中删除“点因子”)比删除@property的性能提高了几乎一个数量级(这些结果在中等规模的应用程序中取平均值)。

在必要的时候,我会在其他地方寻找优化,并首先关注如何编写好的,可维护的代码。此时,如果@property在您的情况下很直观,请使用它。如果没有,请制定方法。

答案 5 :(得分:1)

这正是@property的意思。