1

How do you access the "private" variable behind a Python property?

In the following code, I get Hello World instead of the World World that I expect. I would guess that the property has a different scope that results in self being different in the property than the module. If so, is there a way to access the underlying variable? Or is there a different idiom to use for "code outside the class should use a different getter than code in the class"?

class Foo(): def __init__(self): self._x = 'Hello' self.x = 'World' @property def x(self): return self._x @x.setter def x(self, val): self._x = val foo = Foo() print(foo._x) print(foo.x) 

2 Answers 2

4

You forgot to inherit from object, so you created an old-style class. property setters don't work for old-style classes. If you inherit from object, you get World from both prints, like you expected:

>>> class Foo(object): ... def __init__(self): ... self._x = 'Hello' ... self.x = 'World' ... @property ... def x(self): ... return self._x ... @x.setter ... def x(self, val): ... self._x = val ... >>> foo = Foo() >>> print foo._x World >>> print foo.x World 
Sign up to request clarification or add additional context in comments.

2 Comments

Inferring from the print vs. print(), you are using python2, and it looks like the OP uses python3; if this is the case, your "old style" classes explanation doesn't hold.
@ReblochonMasque: But on Python 3, they would have gotten World both times. I think it's more likely that the questioner is using print with parentheses because they simply aren't very aware of Python version differences and conventional syntax.
2

You are accessing the private variable _x via foo._x.

What is typical in this situation is to not define the x attribute at all, i.e. remove the line self.x = 'World'. That way you are using the property x to access the attribute _x (and because privates aren't really private you can of course also access the attribute directly using _x).

Edit: the first part of my answer was misleading, see user2357112's answer for why you are not getting the expected output.

2 Comments

@QtotheC see my edit, my original answer was misleading.
There is also a difference between protected and private. Protected attributes have a single underscore and they are protected by convention (e.g. signal for other programmers not to use it outside of (sub)class). If you need a stronger protection, you can use double underscores. This is the best you can do in Python. But it's not really private as in other programming languages. It may help in OOP, not finding a way into the subclass, for example.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.