The Python Oracle

What's the difference between a Python "property" and "attribute"?

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: City Beneath the Waves Looping

--

Chapters
00:00 What'S The Difference Between A Python &Quot;Property&Quot; And &Quot;Attribute&Quot;?
00:17 Answer 1 Score 26
00:42 Answer 2 Score 106
01:12 Answer 3 Score 21
02:12 Accepted Answer Score 248
03:01 Thank you

--

Full question
https://stackoverflow.com/questions/7374...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python

#avk47



ACCEPTED ANSWER

Score 248


Properties are a special kind of attribute. Basically, when Python encounters the following code:

spam = SomeObject()
print(spam.eggs)

it looks up eggs in SomeObject1, and then examines eggs to see if it has a __get__, __set__, or __delete__ method -- if it does, it's a property, and Python will call the __get__ method (since we were doing lookup) and return whatever that method returns. If it is not a property, then eggs is looked up in spam, and whatever is found there will be returned.

More information about Python's data model and descriptors.


1 Many thanks to Robert Seimer for the correction on the lookup sequence.




ANSWER 2

Score 106


With a property you have complete control on its getter, setter and deleter methods, which you don't have (if not using caveats) with an attribute.

class A(object):
    _x = 0
    '''A._x is an attribute'''

    @property
    def x(self):
        '''
        A.x is a property
        This is the getter method
        '''
        return self._x

    @x.setter
    def x(self, value):
        """
        This is the setter method
        where I can check it's not assigned a value < 0
        """
        if value < 0:
            raise ValueError("Must be >= 0")
        self._x = value

>>> a = A()
>>> a._x = -1
>>> a.x = -1
Traceback (most recent call last):
  File "ex.py", line 15, in <module>
    a.x = -1
  File "ex.py", line 9, in x
    raise ValueError("Must be >= 0")
ValueError: Must be >= 0



ANSWER 3

Score 26


In general speaking terms a property and an attribute are the same thing. However, there is a property decorator in Python which provides getter/setter access to an attribute (or other data).

class MyObject(object):
    # This is a normal attribute
    foo = 1

    @property
    def bar(self):
        return self.foo

    @bar.setter
    def bar(self, value):
        self.foo = value


obj = MyObject()
assert obj.foo == 1
assert obj.bar == obj.foo
obj.bar = 2
assert obj.foo == 2
assert obj.bar == obj.foo



ANSWER 4

Score 21


The property allows you to get and set values like you would normal attributes, but underneath there is a method being called translating it into a getter and setter for you. It's really just a convenience to cut down on the boilerplate of calling getters and setters.

Lets say for example, you had a class that held some x and y coordinates for something you needed. To set them you might want to do something like:

myObj.x = 5
myObj.y = 10

That is much easier to look at and think about than writing:

myObj.setX(5)
myObj.setY(10)

The problem is, what if one day your class changes such that you need to offset your x and y by some value? Now you would need to go in and change your class definition and all of the code that calls it, which could be really time consuming and error prone. The property allows you to use the former syntax while giving you the flexibility of change of the latter.

In Python, you can define getters, setters, and delete methods with the property function. If you just want the read property, there is also a @property decorator you can add above your method.

http://docs.python.org/library/functions.html#property