为什么python @property getter方法为每次调用运行两次,我可以阻止吗?

时间:2013-04-11 02:30:51

标签: python class properties getter-setter

我有一个行为不端的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'

从ipython登录:

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

  • Python 2.7.3(默认,2012年12月6日,13:30:21)
  • IPython 0.13.1
  • OSX ML与最新的dev-tools更新
  • 一个有很多东西的venv

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

3 个答案:

答案 0 :(得分:2)

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

解决方案是使用

%config Completer.use_jedi = False
解释器中的

,或添加

c.Completer.use_jedi = False

到ipython_config.py文件

答案 1 :(得分:0)

也许它与iPython 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

答案 2 :(得分:0)

Python不在内存中存储该属性。 Python中的属性只是不带()的方法。因此,它将在您每次访问该属性时运行。它违反了IMO属性的目的。您可以将属性方法的结果存储在 init 方法内部的属性中。但是,这是多余的,如果您需要将该值保留在内存中,则最好不要使用属性。

就我而言,我需要存储随请求下载的文本。每次我访问酒店时,它都是从互联网上检索文本。如果您需要执行过程密集型操作,请使用一种方法来完成并将其存储在属性中。如果很简单,请使用属性。