#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    2
    Rep Power
    0

    Looking for explanation of strange behaviour of methods called via property


    I am just undertaking the first steps towards learning python and I have hit upon some strange behavior which I cannot explain. I am writing a simple class, with a set and get method and then exposing those methods through a single interface using property. To make sure everything was working as expected I put a couple of print statements inside the get/set methods, when I call the methods directly the prints get executed, however, when I call the method via the property interface the prints seem to get skipped - although the rest of the method executes correctly.

    I'm not sure if that explains very clearly what I am seeing, so I have boiled the code down to its elements

    Code:
    class Storer:
      def setx(self,x):
        print "- Storing " + str(x)
        self._x = x
        
      def getx(self):
        print "- Getting " + str(self._x)
        return (self._x)
        
      x = property(getx,setx)
      
    store = Storer()
    
    print "Calling method directly:"
    store.setx("foo")
    print "Retrieved " + store.x
    
    print "Calling through property:"
    store.x = "bar"
    print "Retrieved " + store.x
    This results in the following output:

    Code:
    Calling method directly:
    - Storing foo
    - Getting foo
    Retrieved foo
    Calling through property:
    Retrieved bar
    At first I thought this might be a windows bug, but the same behavior happens running this on BSD too. I'm sure this is a simple issue that anyone with a few months experience can explain, however, I don't like not being able to explain why something happens - it makes me feel like I do not have a complete grasp of the language.

    Cheers

    Jammib

    EDIT

    Looking at this again, there is something else that makes no sense to my addled brain. It looks like the first run of the get method executes the print statement, but the second one doesn't
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    43
    Rep Power
    3
    I think I have figured it out.

    edit: tinkering with it right now. My previous answer was wrong I believe.

    edit2: Figured it out. After you said store.x = "bar" , it no longer is calling a function. It literally becomes a string, unable to change the real proterty using setx because now x does NOT = property(getx,setx)

    After you run your program, tack on these lines again and you'll see what I mean. The original function has become broken because x itself no longer works properly:


    Code:
    print "Calling method directly:"
    store.setx("foo")
    print "Retrieved " + store.x


    It returns the results:

    Code:
    Calling method directly:
    - Storing foo
    - Getting foo
    Retrieved foo
    Calling through property:
    Retrieved bar
    Calling method directly:
    - Storing foo
    Retrieved bar
  4. #3
  5. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,996
    Rep Power
    481
    This is the same code as that of your first post with parentheses around the argument to the print function. Run the program using python3. It works as we'd expect. What you've discovered could be some sick artifact of the python developers having tried to wedge properties into python2. I haven't read about properties in python2
    Code:
    class Storer:
      def setx(self,x):
        print("- Storing " + str(x))
        self._x = x
        
      def getx(self):
        print("- Getting " + str(self._x))
        return (self._x)
        
      x = property(getx,setx)
      
    store = Storer()
    
    print( "Calling method directly:")
    store.setx("foo")
    print( "Retrieved " + store.x)
    
    print( "Calling through property:")
    store.x = "bar"
    print( "Retrieved " + store.x)
    [code]Code tags[/code] are essential for python code and Makefiles!
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    2
    Rep Power
    0
    I fixed it \o/

    The problem was on the first line with the class definition:

    Code:
    class Storer:
    this sets the class up as an old style class, to use properties I needed to define the class as a new style class:

    Code:
    class Storer(object):
    and now everything works as expected;

    Code:
    Calling method directly:
    - Storing foo
    - Getting foo
    Retrieved foo
    Calling through property:
    - Storing bar
    - Getting bar
    Retrieved bar
    Thanks for all your help guys, and for such quick responses it's good to know that there are such active, helpful members on the forum.

    Cheers

    Jammib

    Comments on this post

    • b49P23TIvg agrees : Oh! I forgot about object. I switched to py3k beta in 2008. Ignored further python2 development.

IMN logo majestic logo threadwatch logo seochat tools logo