1

I am running the following code:

class testClass:
    def __init__(self, left, width):
        self.__left = left
        self.__width = width

    @property
    def left(self):
        return self.__left

    @left.setter
    def left(self, newValue):
        self.__left = newValue

    @property
    def width(self):
        return self.__width

    @width.setter
    def width(self, newValue):
        self.__width = newValue

    def right(self):
        return self.__width + self.__left

    def rightFixed(self):
        return self.width + self.left

test = testClass(10,5)
test.left = 50
print test.right()
print test.rightFixed()

I am getting the values

15
55

Can anyone explain why the first method test.right() is giving the value 15, whereas if I call the test.rightFixed() value it gives me the appropriate value? I have looked in the interpreter, and _testClass__left after the code has run gives me 10, whereas it should give me 50. The @left.setter property doesn't seem to be updating the self.__left, rather it seems to be making it's own copy.

EDIT: I should also note, I am running 2.7.6. As Games Brainiac pointed out, this works fine in python 3+.

14
  • I'm getting 55, 55. Using python 3 tho. Commented Oct 21, 2014 at 2:09
  • I forgot to mention I am using 2.7. Commented Oct 21, 2014 at 2:10
  • 1
    Why are you using double underscores? Commented Oct 21, 2014 at 2:12
  • 2
    @ixwt: double underscore isn't private, it's superprivate, and pretty unpythonic. You're teammate is in a world of hurt if he is going to try to write Python as if it were C++. Commented Oct 21, 2014 at 2:17
  • 2
    Unless you're trying to "avoid name clashes of names with names defined by subclasses", using __ is nine kinds of silly, and ugly to boot. Commented Oct 21, 2014 at 2:28

2 Answers 2

5

Add (object) to your class. After Python 2.6 a new data model was introduced. See https://docs.python.org/2/reference/datamodel.html#newstyle.

See the comments by DSM for why Python3 and Python2 treat it different.

class testClass(object):
    def __init__(self, left, width):
        self.__left = left
        self.__width = width

    @property
    def left(self):
        return self.__left

    @left.setter
    def left(self, newValue):
        self.__left = newValue

    @property
    def width(self):
        return self.__width

    @width.setter
    def width(self, newValue):
        self.__width = newValue

    def right(self):
        return self.__width + self.__left

    def rightFixed(self):
        return self.width + self.left

>>test = testClass(10,5)
>>test.left = 50
>>print test.right()
55
>>print test.rightFixed()
55
Sign up to request clarification or add additional context in comments.

9 Comments

This seems to fix the problem. Although I am curious as to why.
This solves the problem because you need to be a new-style class to have descriptor support, and properties are descriptors. "(Note that descriptors are only invoked for new style objects or classes (a class is new style if it inherits from object or type)." See here for more than you care to know.
@DSM Not really. property is lazy by default in py2, its not in py3.
@GamesBrainiac: ? property doesn't apply to old-style classes.
@GamesBrainiac: property is not designed to work with old-style classes. I've noticed in particular that __set__() never gets called. From the python documentation on descriptors: "descriptors only work for new style objects and classes". This fact is repeated several times on the descriptor documentation page.
|
0

Because Python will 'name-mangle' double underscores. If you must use double underscores, then when you access them you have to do it as follows:

test._testClass__left

But instead you should just use a single underscore, which indicates a private variable, and you can continue on normally.

3 Comments

This isn't the issue here, though.
This doesn't seem to fix the issue. And besides, won't all the values be mangled? A single underscore still gives me an incorrect value.
Ah, yes, @Parker got to it, I didn't even notice he forgot to inherit from object

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.