Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python@property与方法性能-使用哪一种?_Python_Performance_Properties - Fatal编程技术网

Python@property与方法性能-使用哪一种?

Python@property与方法性能-使用哪一种?,python,performance,properties,Python,Performance,Properties,我编写了一些使用对象属性的代码: class Foo: def __init__(self): self.bar = "baz" myFoo = Foo() print (myFoo.bar) 现在我想做一些奇特的计算来返回bar。我可以使用@property使方法充当属性bar,或者我可以重构代码以使用myFoo.bar() 我是否应该返回并将参数添加到我的所有栏访问或使用@属性?假设我的代码库现在很小,但由于熵,它会增加。如果它在逻辑上是对象的一个属性/属性,我会说

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

class Foo:
    def __init__(self):
        self.bar = "baz"
myFoo = Foo()
print (myFoo.bar)
现在我想做一些奇特的计算来返回
bar
。我可以使用
@property
使方法充当属性
bar
,或者我可以重构代码以使用
myFoo.bar()


我是否应该返回并将参数添加到我的所有
访问或使用
@属性
?假设我的代码库现在很小,但由于熵,它会增加。

如果它在逻辑上是对象的一个属性/属性,我会说将其保留为属性。如果它很可能变成参数化,我的意思是你可能想调用
myFoo.bar(someArgs)
,那么现在就咬紧牙关,把它变成一个方法


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

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

至于在使用方法和
@属性
之间进行选择,这是一个品味的问题,但由于属性将自己伪装成简单的属性,因此不需要进行任何详细说明。一种方法表明它可能是一种昂贵的操作,使用代码的开发人员会考虑缓存值而不是一次又一次地获取它。 所以,不要继续表现,总是考虑维修性和性能。随着时间的推移,计算机变得越来越快。这并不代表代码的可读性


简而言之,如果您想得到一个简单的计算值,
@property
是一个很好的选择;如果你想计算一个复杂的值,一个方法会更好。

这正是@property的用意。

我会进行重构,但只是为了风格问题——我似乎更清楚地看到,通过一个方法调用,“奇特的计算”可能正在进行,而我希望一个属性几乎是不可操作的,但这是品味的问题


别担心装饰师的表现。。。如果您认为这可能是一个问题,请测量这两种情况下的性能,看看它增加了多少(我的猜测是,如果与您奇特的计算相比,它将是完全可以忽略不计的)。

当性能很容易测量时,不必担心性能:

$ 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中用一个向上箭头从第一个案例构建了它,它重复了linebreak结构,但没有提示!)

因此,除非你知道200+纳秒左右会起作用(你正试图最大限度地优化一个紧密的内部循环),否则你可以使用属性方法;如果您进行一些计算以获得该值,200+纳秒当然将成为总时间的一小部分


我同意其他的答案,如果计算变得太重,或者你可能想要参数,等等,一个方法更可取——类似地,我会补充,如果你需要把可调用的东西藏在某个地方,但只在以后调用它,以及其他奇特的函数编程技巧;但是我想量化性能点,因为
timeit
使得这样的测量非常容易!)

我同意这里大多数人的说法,几年前我在Python中构建水文模型时做了很多测量,发现使用@property所带来的速度完全被计算所掩盖

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


如果有必要,我会在其他地方寻找优化,并首先关注编写好的、可维护的代码。在这一点上,如果@property在您的案例中是直观的,请使用它。如果不是,请创建一个方法。

如果不计算
x
实例创建,结果会更接近(百分比),(我在iPython中使用了
%timeit
魔术函数):
x=x();%timeit x.y
->1000000个循环,每个循环最好3:211纳秒;
x=x();%timeit x.y()
->10000000个循环,每个循环最好3:169纳秒