views:

107

answers:

5
class ClassName(object):
    """
    """    
    def __init__(self, foo, bar):
        """
        """
        self.foo = foo # read-write property
        self.bar = bar # simple attribute

    def _set_foo(self, value):
        self._foo = value

    def _get_foo(self):
        return self._foo

    foo = property(_get_foo, _set_foo)

a = ClassName(1,2)
#a._set_foo(3)
print a._get_foo()

When I print a._get_foo() the function _get_foo prints the variable self._foo . But where does it come from? self._foo and self.foo are different, aren't they?

EDIT: The problem is that I still not understand what property does. Give me some time.

A: 

According to your code, it "comes from" _set_foo. In your init, when you do self.foo = foo, that calls _set_foo(1), which performs self._foo = 1.

You can see this more clearly if you add a print statement inside _set_foo().

Chris S
Why does self.foo = foo calls _set_foo(1) ?
kame
@kame: you're setting value to the `foo`, that's why setter is called.
SilentGhost
+1  A: 

Docs for property explain how it's supposed to be used. There is no difference between these lines:

self.foo = foo # read-write property

and

a.foo = 3

You're also not supposed to call setters and getters manually.

eta: if you don't understand what property does after looking at the examples provided in the docs and reading our answers, you perhaps should just abstain from using it. It really is not the most essential of Python's features. You might want to start with a simpler example, which is easy to understand:

>>> class ClassName(object):
    def __init__(self, foo):
        self.foo = foo


>>> a = ClassName(1, 2)
>>> a.foo
1
>>> a.foo = 42
>>> a.foo
42
SilentGhost
The point is that I still not understand what property does.
kame
Thank you SilentGhost!
kame
+1  A: 

You define foo to be a property with getters and setters.

Those getters and setters use the variable self._foo, since you coded it that way:

def _set_foo(self, value):
  self._foo = value

In your case you would get a problem if you had a slightly different implementation:

class ClassName(object):
    """
    """    
    def __init__(self,):
        """
        """
        pass

    def _set_foo(self, value):
        self._foo = value

    def _get_foo(self):
        return self._foo

    foo = property(_get_foo, _set_foo)


 a = ClassName()
 print a.foo
 -> AttributeError

 b = ClassName()
 b.foo = 1 # implicitely sets self._foo !
 print b.foo
 >> OK, this is 1

As it happens you indeed should set self.foo in the __init__ since the setter creates self._foo. (Or initialize self._foo in the __init__ directly of course).

So, where do self.foo and self._foo come from? It's explicit in the code. self.foo is a property, and self._foo is the variable in which you decided to keep the value of that property.

extraneon
+1  A: 
Tendayi Mawushe
But why do I need a variable _foo? Isn't foo enough? Its hard to understand.
kame
@kame foo alone is not enough if you need to use a property. However unless you have something more complicated to do do not use a property, just use an attribute named foo. In Python unlike in Java for example you can always change that to a property with the same name later without affecting any client code. So do not use any getter and setter methods unless they will have business logic in them.
Tendayi Mawushe
Thanks a lot!!!
kame
+2  A: 

I really recommend this site:

http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

A good explanation of the property-function.

kame
+1 never heard of proprieties myself until now, and looks like this link explains it very nicely
Lo'oris
The half of the programmers haven't heard of it.
kame