Python中@property与方法性能的对比 - 该选择哪个?

15 投票
6 回答
9021 浏览
提问于 2025-04-15 12:58

我写了一些代码,这些代码使用了一个对象的属性:

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

现在我想进行一些复杂的计算来返回 bar。我可以使用 @property 来让方法像属性 bar 一样工作,或者我可以重构我的代码,使用 myFoo.bar()

我应该回去给所有的 bar 访问加上括号,还是使用 @property 呢?假设我的代码现在很小,但由于各种原因,它会逐渐增多。

6 个回答

8

在这种情况下,我觉得选择最合理的选项要好得多。对于这些小差别,你不会感受到明显的性能损失。更重要的是,你的代码要易于使用和维护。

至于在使用方法和 @property 之间的选择,这主要是个人喜好。不过,因为属性看起来像简单的属性,所以不应该有太复杂的操作。方法则表示可能会进行一些比较耗时的操作,使用你代码的开发者可能会考虑把这个值缓存起来,而不是一次又一次地去获取它。

所以,再次强调,不要只关注性能,始终要考虑可维护性和性能之间的关系。随着时间的推移,计算机的速度会越来越快,但代码的可读性却不会。

总之,如果你想得到一个简单的计算值,使用 @property 是个不错的选择;如果你想得到一个复杂的计算值,使用方法会更合适。

21

担心性能其实没必要,因为测量性能非常简单:

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

(在我这台慢慢的笔记本上——如果你想知道为什么第二种情况没有二级提示符,那是因为我用上箭头从第一种情况复制过来的,这样会重复行结构,但不会重复提示符!)

所以,除非你知道在某些情况下200纳秒以上的时间会很重要(比如你在优化一个非常紧凑的循环),否则你可以放心使用属性的方法;如果你需要进行一些计算来得到值,那么这200纳秒在总时间中就显得微不足道了。

我同意其他回答的观点,如果计算变得太复杂,或者你可能需要参数等等,使用方法会更好——同样的,如果你需要把可调用的东西存起来但稍后再调用,或者其他一些高级的函数编程技巧;不过我想强调一下性能的问题,因为timeit让这种测量变得非常简单!

22

如果这个东西在逻辑上是对象的一个属性,我建议你把它当作属性来处理。如果你觉得它可能会变成一个需要参数的东西,比如你可能想要调用 myFoo.bar(someArgs),那么现在就果断把它做成一个方法吧。

在大多数情况下,性能问题一般不会是个大问题。

撰写回答