Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need property in Python?

Tags:

python

I understand one of the main purpose to use property is for validation and formatting. For example, I have a User class shown below. And I want the firstname and lastname are capitalized when they are being set. Why do I need property if I can write the following code to achieve the same formatting result?

class User:
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname

    def __setattr__(self, attr, value):
        if attr == 'firstname':
            self.__dict__[attr] = value.capitalize()
        elif attr == 'lastname':
            self.__dict__[attr] = value.capitalize()
like image 672
David Zheng Avatar asked Feb 10 '23 20:02

David Zheng


2 Answers

You're right, you don't need properties to perform validation on setting an attribute, or to perform special behavior when doing attribute lookup. But properties are more readable and nicer to write. I'd stick to using __getattr__ and __setattr__ in cases where you want to dynamically access attributes (that is, you don't know what attributes you'll have at the time of class definition). Otherwise, use properties, as they are a very recognizable python idiom.

In fact, in this case where you have two properties which are performing the same validation, I might use a descriptor:

class NameDescriptor(object):

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

    def __get__(self, obj, objtype):
        return getattr(obj, self.key)

    def __set__(self, obj, val):
        setattr(obj, self.key, val.capitalize())

class User(object):

    firstname = NameDescriptor('_firstname')
    lastname = NameDescriptor('_lastname')

    def __init__(self, first, last):
        self.firstname = first
        self.lastname = last

A demo of how this works:

>>> user = User('steve', 'martin')
>>> user.firstname
'Steve'
>>> user.firstname = 'dean'
>>> user.firstname
'Dean'
like image 197
jme Avatar answered Feb 12 '23 10:02

jme


A totally cool point about properties in Python is that you can go back to a mess you've created in an application in the past and fix it without breaking existing code.

In Java, for example, having set a class variable as private, you provide getter and setter functions, and usually put some logic in these so as to avoid absurd values.

In Python, since class variables are public by default, it's very easy to create a situation where users of your class will find all sorts of creative ways of inputing absurd values.

By the time you realize that, if you substantially change the logic of your app to prevent theses absurd values, it's likely you'll create a new version of your app that's not backward compatible with the first one. That usually makes very unhappy users.

Properties give you a way around this: fix the mess, while keeping backward compatibility.

If you want more details on how this works, this page:

'http://www.programiz.com/python-programming/property'

explains it well.

like image 25
Karpov Avatar answered Feb 12 '23 10:02

Karpov