为什么python的@property getter方法每次调用都要运行两次,我能停止它吗?



我有一个行为不端的iPython运行两次getter(但不运行setter):

class C(object):
    @property
    def foo(self):
        print 'running C.foo getter'
        return 'foo'
    @foo.setter
    def foo(self, value):
        print 'running setter'

来自ippython的日志:

In [2]: c = C()
In [3]: c.foo
running C.foo getter
running C.foo getter
Out[3]: 'foo'
In [4]: c.foo = 3
running setter

Env is

  • Python 2.7.3 (default, Dec 6 2012, 13:30:21)
  • IPython 0.13.1
  • 带有最新开发工具更新的OSX ML
  • 一个有很多东西的venv

这不再是一个代码问题,因为这似乎不是属性正常工作的方式。

这是一个老问题,但是这个问题在ippython 6.0.0中仍然存在

解决方法是使用
%config Completer.use_jedi = False

,或者添加

c.Completer.use_jedi = False

到ipython_config.py文件

可能与ippython issue 62有关。这个问题已经解决了,但仍然影响着我和其他人。

要复制这个问题的特殊风格(这似乎是我的环境所独有的),将该文件保存为doubletake.py

class C(object):
    @property
    def foo(self):
        print 'running C.foo getter'
        return 'foo'
    @foo.setter
    def foo(self, value):
        print 'running setter'
if __name__ == '__main__':
    print 'Calling getter of anonymous instance only runs the getter once (as it should)'
    C().foo
    print "Call named instance of C's foo getter in interactive iPython session & it will run twice"
    from doubletake import C
    c = C()
    c.foo

然后在iPython

中运行这个交互式会话
from doubletake import C
C().foo
# running C.foo getter
# 'foo'
c=C()
c.foo
# running C.foo getter
# running C.foo getter
# 'foo'
%run doubletake
# Calling getter of anonymous instance only runs the getter once (as it should)
# running C.foo getter
# Call named instance of C's foo getter in interactive iPython session & it will run twice
# running C.foo getter

Python不将该属性存储在内存中。Python中的属性只是一个不带()的方法。因此,它将在每次访问该属性时运行。它违背了属性的目的。您可以将属性方法的结果存储在init方法的属性中。然而,这是多余的,如果你需要值在内存中持久化,你最好一开始就不使用属性。

在我的例子中,我需要存储随请求下载的文本。每次我进入房子它都会从网上检索文本。如果你需要做一些过程密集型的事情,使用一个方法来做,并将它存储在一个属性中。

最新更新