2

I have a misbehaving iPython that runs getters twice (but not setters):

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

Log from 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 is

  • Python 2.7.3 (default, Dec 6 2012, 13:30:21)
  • IPython 0.13.1
  • OSX ML with recent dev-tools update
  • a venv with lots of stuff

This is no longer a code question, as it seems this is not the way properties should normally work.

hobs
  • 18,473
  • 10
  • 83
  • 106
  • Python 2.7.3 (default, Dec 6 2012, 13:30:21) IPython 0.13.1 -- An enhanced Interactive Python. – hobs Apr 11 '13 at 02:31
  • Ran it in a vanilla Python 2.7.3 session and no repeat getting. So it's an IPython "feature" or a quirk in my install/config. – hobs Apr 11 '13 at 02:32
  • 3
    I don't see it happening even with IPython. However, it wouldn't surprise me if IPython did that in some circumstances. IDEs will sometimes evaluate expressions in order to be able to autocomplete or give other useful info about an object. In order to show you methods available on `c.foo`, for instance, it has to evaluate `c.foo`. – BrenBarn Apr 11 '13 at 02:43
  • 1
    @hobs Running Ipython 0.13.1 too, I don't get a repeat print. – Thomas Orozco Apr 11 '13 at 03:01
  • Weird, I'm all alone in the twilight zone. Maybe it's my OSX Mountain Lion install or something. Not worth bothering with since it doesn't happen with a noninteractive session. Just freaked me out and confused some debugging I was doing. Thanks @Thomas and BrenBam for the attempt to recreate. – hobs Apr 11 '13 at 05:17
  • @hobs That's weird; I'm using OSX too here : ( – Thomas Orozco Apr 11 '13 at 05:29
  • Darn. Must be something else. Will post when I figure it out. – hobs Apr 11 '13 at 17:46

3 Answers3

2

This is an old question, but the problem persist in IPython 6.0.0

The solution is to use

%config Completer.use_jedi = False

in the interpreter, or add

c.Completer.use_jedi = False

to the ipython_config.py file

Vrekrer
  • 176
  • 1
  • 7
0

Perhaps it is related to iPython issue 62. That issue has been closed but still affects me and others.

To duplicate my particular flavor of this issue (that does seem to be unique to my environment), save this file as 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

Then run it with this interactive session in 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
hobs
  • 18,473
  • 10
  • 83
  • 106
0

Python does not store the property in memory. A property in Python is just a method without (). Therefore, it will run every time you access the property. It defeats the purpose of properties IMO. You can store the result of the property method, inside an attribute inside of the init method. However, this is redundant and you might as well just not use properties in the first place if you need the value to be persistent in memory.

In my case, I needed to store text downloaded with requests. It was retrieving the text from the internet every time I accessed the property. If you need to do something that is process intensive, use a method to do that and store it in an attribute. If it a simple, use a property.

JasonG
  • 127
  • 1
  • 8
  • 1
    You can memoize your process-intensive properties: https://stackoverflow.com/questions/1988804 – hobs Aug 29 '18 at 22:29
  • 1
    Properties are attributes upgraded to functions, they are meant to be used with an attribute from init. They are in no way a caching or storage mechanism ! Nor are they a replacement for functions. – Mihai Andrei Mar 13 '19 at 15:30