-3

What is the difference between @property, @property.setter and getattr(), setattr(). When will I use them? If both are the same, which one is preferred to use in python 3.x?

I am new to python and not understanding where to use and how to use them with OO python

I have gone through many websites, but I'm not sure which one to use. Please give me some real time example. Appreciate your help.

EX:

getattr()

class emp: name='Harsh' salary='25000' def show(self): print self.name print self.salary e1 = emp() print getattr(e1,'name') setattr(e1,'height',152) @ property

class P:

def __init__(self,x):
    self.x = x

@property
def x(self):
    return self.__x

@x.setter
def x(self, x):
    if x < 0:
        self.__x = 0
    elif x > 1000:
        self.__x = 1000
    else:
        self.__x = x
Sanjay Varma
  • 5
  • 1
  • 2
  • 2
    getattr and setattr are usually used by calling code when the name of the attribute is stored in a variable. – soundstripe Jul 02 '18 at 02:27
  • 1
    Please cite the source of that example code ... https://www.python-course.eu/python3_properties.php – Matthew Story Jul 02 '18 at 04:27
  • BTW, making `name` a class attribute instead of an instance attribute is a bit weird, unless you only have 1 employee. :) – PM 2Ring Jul 02 '18 at 04:48

1 Answers1

7

In python we generally do not use getter and setter methods, instead preferring to directly get and set attributes wherever possible as it is far simpler and more intuitive than intermediating access to values through getter and setter methods.

In the (fairly) rare case where you do need dynamic setters and getters, the @property decorator is the preferred way of defining dynamic setters and getters that can be used via . notation:

class Foo:
    def __init__(self, x=None):
        self.x = x

    @property
    def x(self):
        return self._x

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

These can be used in concert with getattr and setattr, which allow you to dynamically access attributes of an object by the attribute name:

foo = Foo()
getattr(foo, "x")    # 0
setattr(foo, "x", 1) # Same as foo.x = 1
foo.x       # 1

A more apropos question might be what is the difference between a @property and __getattr__ and __setattr__ which allow for dynamic property access similar to property but for any possible name:

class Foo(object):
    def __init__(self, x=None):
        self._other_values = {}
        self.x = x

    def __getattr__(self, k):
        try:
            return self._other_values[k]
        except KeyError:
            raise AttributeError(k)

    def __setattr__(self, k, v):
        if k == "_other_values":
            return super(Foo, self).__setattr__(k,v)
        if k == "x":
            v = v or 0
        self._other_values[k] = v

Which will function identically to the example above.

Matthew Story
  • 3,573
  • 15
  • 26