Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python property vs method when no access to attribute is needed?

I am reading "Python programming for the absolute beginner" and in there there is this piece of code:

@property
def mood(self):
    unhappiness = self.hunger + self.boredom
    if unhappiness < 5:
        m = "happy"
    elif 5 <= unhappiness <= 10:
        m = "okay"
    elif 11 <= unhappiness <= 15:
        m = "frustrated"
    else:
        m = "mad"
    return m

All it does is calculate on-the-fly and return the calculation. It doesn't provide access to a private attribute or any attribute of the class. Is this better as property rather than method?

like image 456
h3dkandi Avatar asked Dec 10 '13 22:12

h3dkandi


People also ask

What is the difference between property and method in Python?

Ans: A property is a named attribute of an object. Properties define the characteristics of an object such as Size, Color etc. or sometimes the way in which it behaves. A method is an action that can be performed on objects.

When should I use property Python?

Python's property() is the Pythonic way to avoid formal getter and setter methods in your code. This function allows you to turn class attributes into properties or managed attributes. Since property() is a built-in function, you can use it without importing anything.

Is attribute the same as property Python?

In python, everything is an object. And every object has attributes and methods or functions. Attributes are described by data variables for example like name, age, height etc. Properties are special kind of attributes which have getter, setter and delete methods like __get__, __set__ and __delete__ methods.

What is the difference between attribute and property?

An attribute is a quality or character ascribed to or considered to belong to, or be inherent in, a person or thing. A property is a quality or characteristic belonging to a person or thing, with its original use implying ownership, and also either being essential or special.


3 Answers

Properties are not intended for providing access to a private attribute. Properties are intended to give you the option of making zero-argument methods accessible as if they were attributes, so that a given "attribute" can be implemented as either a calculation or an actual attribute, without changing the interface of the class.

As such, it's usually not really a question of "better", but rather a design decision with pros and cons that depend on the context.

In this case, whatever this object is supports x.hunger, x.boredom and x.mood. Why not x.mood()? You could, although that exposes permanently in the interface that it is a calculation and is not stored.

If a prior version of the class had a "real" mood attribute, and a required invariant of the object meant that any internal method updating boredom or hunger had to also carefully set mood to be consistent, then introducing the property would be an excellent refactor; the interface stays the same, but the invariant is now guaranteed to always hold, rather than having to be carefully maintained. A whole field of bugs are made impossible to occur.

On the other hand, if mood is expensive to calculate, or has side effects, then it likely would be much better as a normal method. Making it look like an attribute access means that client code programmers will likely think of it as an attribute access, which is cheap and non-destructive; this would be a rich source of bugs or performance problems.

like image 79
Ben Avatar answered Oct 04 '22 19:10

Ben


It's just a matter of taste.

A property is used where an access is rather cheap, such as just querying a "private" attribute, or a simple calculation.

A method is used where a rather "complicated" process takes place and this process is the main thing.

People are used to using getter and setter methods, but the tendency is used for useing properties more and more.

Take, as an example, the Serial class of pyserial. It has - as a heritage - methods such as getBaudRate() and setBaudRate(), but recommends to use baudrate as a reading and writing property for querying and setting the baud rate.

like image 38
glglgl Avatar answered Oct 04 '22 20:10

glglgl


I do not think there is any real difference.

It just allows you to do obj.mood instead of obj.mood()

like image 5
qwertynl Avatar answered Oct 04 '22 21:10

qwertynl