2

Possible Duplicate:
What is the benefit to using a ‘get function’ for a python class?

I just started to read Python, but I wonder why does Python need setter and getter at all? it already have object variables which act like property

Consider

class C(object):
    def _init_(self):
        self._x = None

    def get_x(self):
        return self._x

    def set_x(self, value):
        self._x = valu
    x = property(get_x, set_x)

Can we just use C.x = "value" to do what we want to do here? what is the benefit of property?

BTW, creating property/setter/getter in this way is cumbersome to me, is there any way to simplify this? like

class C()
   has_attributes("x", "y", "z")
Community
  • 1
  • 1
woosley. xu
  • 182
  • 1
  • 12
  • 4
    You don't need getters and setters in Python. – David Robinson Dec 25 '12 at 06:13
  • In addition to what brenbarn posted, consider [Python @property versus getters and setters](http://stackoverflow.com/questions/6618002/python-property-versus-getters-and-setters) – Burhan Khalid Dec 25 '12 at 06:29
  • Also note that you may want to *not* initialize `self._x` to `None`, so as to catch problems with code that tries to access it before it is set. In this case, you may not even need to define `__init__()`. – Eric O. Lebigot Dec 25 '12 at 06:46

3 Answers3

4

You can use a property to obtain what you want:

class C(object):
    def _init_(self):
        self._x = None
    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

Then you can access the attribute with the usual attribute syntax:

c = C()
c.x = 10    #calls the setter
print(c.x)  #calls the getter

There are some reasons to use a property instead of a plain data attribute:

  • You can document the attribute
  • You can control the access to the attribute, either by making it read-only or by checking the type/value being set
  • You do not break backwards compatibility: if something was a plain instance attribute and then you decide to transform it into a property the code that worked with the attribute will still work. If you used get/set explicit methods all the code that used the old API would have to change
  • It's more readable then using explicit get/set methods.
Bakuriu
  • 98,325
  • 22
  • 197
  • 231
4

Use plain attributes:

class C(object):
    def __init__(self):
        self.x = None

Later, when and if it would be necessary, x can be changed to a property. The beauty of "@property" it that is allows developer not to use getters, setters and "@property".

Mikhail Korobov
  • 21,908
  • 8
  • 73
  • 65
2
class C(object):
    def _init_(self):
        self._x = None

    def get_x(self):
        return self._x

    def set_x(self, value):
        self._x = value

    x = property(get_x, set_x)

now you can use c.x = "foo" with the set and gets, transparently.

The purpose of a set and getter is don't expose the class internals.

Imagine that in the future

self._x 

changes to

sql.save(id(self), value)

and get_x to:

value= sql.sql(id(self))
return convertFromDbFormatToExpectedApiFormat(value)

You will only have to change the code of getter and setters in only that class, not change all the classes that communicates with it.

class C(object):
    def _init_(self):
        self.sql = DDBB()

    def get_x(self):
        dbregistry = self.sql.fetch(id(self))
        return convertFromDbFormatToExpectedApiFormat(dbregistry)

    def set_x(self, value):
        self.sql.save(id(self), value)

    x = property(get_x, set_x)
  • Your advice is applicable to Java, but Python callers would not have any trouble with a class that converted an attribute "x" to a property "x" implemented with "get_x" and "set_x". – PaulMcG Dec 25 '12 at 09:20
  • I'm not fully understanding your argument... Could elaborate? I think is more clear use get and set and property when you need do some non-trivial logic, and use decorator @property only if expected trivial, if any, logic. Also explicit setter and getter is more legible for multi-language developers, and (at least ver. 2.7) openly elaborated in the python docs. – Jorge Díaz Díaz Dec 25 '12 at 15:15
  • 2
    If your only behavior in assigning to the `x` property to call `set_x` to set `object._x`, just define the attribute as `x` and assign to it directly as `object.x`. If things change in the future (such as adding db persistence as you describe), then implement the setters and getters. No change needed in the callers - they used to set the attribute with `sth.x = 100`, and the new code will be `sth.x = 100` - hey! no change after all! (Unlike Java, in which this kind of change, while syntactically the same, requires client code to recompile.) – PaulMcG Dec 25 '12 at 20:29
  • 1
    Phillip Eby may have explained this better in http://dirtsimple.org/2004/12/python-is-not-java.html – PaulMcG Dec 25 '12 at 20:30