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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么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'

从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

环境是

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

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

答案

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

解决方案是使用

%config Completer.use_jedi = False

在翻译中,或添加

c.Completer.use_jedi = False

到ipython_config.py文件

另一答案

也许它与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
另一答案

Python不会将属性存储在内存中。 Python中的属性只是一个没有()的方法。因此,它将在您每次访问该属性时运行。它违背了IMO财产的目的。您可以将属性方法的结果存储在init方法内的属性中。但是,这是多余的,如果您需要在内存中持久化值,您可能也不会首先使用属性。

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

以上是关于为什么python @property getter方法为每次调用运行两次,我可以阻止吗?的主要内容,如果未能解决你的问题,请参考以下文章

ruby Gett媒体基准测试

Python中,关于@property装饰器

scala scala 类

[python学习] 介绍python的property,以及为什么要用setter,一个小栗子

python类中的@property和@staticmethod分别有什么用,还有其他的吗?

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