November 3rd, 2012, 01:55 AM
-
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
November 3rd, 2012, 02:29 AM
-
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
November 3rd, 2012, 02:43 PM
-
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!
November 4th, 2012, 01:01 AM
-
I fixed it \o/
The problem was on the first line with the class definition:
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