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()
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'
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With