Getter vs属性为只读或计算成员数据

时间:2016-05-16 00:56:20

标签: python properties

在Python中,成员数据的getter和setter通常不受限制而不是属性。 reasons强调我们可能希望透明地交换计算和值的情况,以及可能在单个快递中读取和分配成员的情况。

那些不能或不能合理分配给会员的会员呢?在这种情况下,是否有任何结构性原因要求吸气剂或财产?

我想到的具体情况是一个具有可能被缓存的计算成员的类。

1 个答案:

答案 0 :(得分:1)

这取决于你的想法应该如何被认为是。它是一个可以轻易访问的属性,还是看起来需要“工作”来获取?

如果您的特征是缓存值,并且访问站点无法影响该特征的检索方式,那么需要表明您正在使用getter函数意味着您告诉消费者当他们不需要知道它时,需要执行一个过程。为什么要让某人想到你说他们不需要知道的设计后果?

但是,假设您的getter可能需要在访问站点进行控制,例如在某些情况下,您可能希望使缓存无效。它可能在消费者代码中并不常见,但这是由你来决定的。在这种情况下,你需要一个带参数的getter,或者一个reset方法来使用你的缓存属性。

最后,可能过头了,更喜欢方法优于属性的原因是属性描述符的访问时间比方法调用稍慢,所以如果在紧密循环内深入访问特征,使用属性,甚至一个缓存的,可以产生可衡量的影响。

编辑 - 澄清描述符的成本

检索方法或描述符时,您正在查找名称的值。如果你正在使用一个函数,它只是在查找后调用。如果您正在使用描述符(@property),则会检测到该描述符,并检索并调用描述符的__get__方法。这意味着描述符具有额外的查找步骤。这个成本是最小的,并且对于常见用途来说实际上是不可测量的,但是如果它在内循环中经常访问非常,那么这个价格就会累积。

In [1]: class Method(object):
   ...:     def get_my_value(self):
   ...:         return 1
   ...:

In [2]: class Property(object):
   ...:     @property
   ...:     def my_value(self):
   ...:         return 1
   ...:

In [3]: M = Method()

In [4]: %timeit M.get_my_value()
The slowest run took 14.74 times longer than the fastest. This could mean that an intermediate result is being cached
10000000 loops, best of 3: 133 ns per loop

In [5]: P = Property()

In [6]: %timeit P.my_value
The slowest run took 8.09 times longer than the fastest. This could mean that an intermediate result is being cached
10000000 loops, best of 3: 181 ns per loop