Cheerful Curmudgeon

A complete lack of ideas and the power to express them.

  • Home
  • About Me
    • Art Zemon’s PGP Key
    • Privacy Policy
  • Bede BD-4C
    • Hall of Fame
  • Piper Arrow

Python Properties and @property

September 29, 2013 Art Zemon

My son pointed me at PyCharm and, while poking through it’s built-in “intentions,” I discovered Python’s @property decorator, which led me to learn more about the Pythonic way to handle class properties. Unlike Java and C++, Python encourages you to create public class attributes (a/k/a properties). Here is an example:

class Hero(object):
    def __init__(self, **kwargs):
        self.name = kwargs['name']

if '__main__' == __name__:
    superman = Hero(name='Kal El')
    print superman.name
    superman.name = 'Clark Kent'
    print superman.name

# Kal El
# Clark Kent

That works while being beautifully readable. A hero has a name. You can print the name and, when the hero moves to a new planet, you can change the name.

Python makes it easy to change the behavior of the Hero class, and this is markedly different from what you can do in many other languages. Let’s say that you want the Hero class to store not just the hero’s name but also his first name and his last name. The obvious way to implement that would be in the “setter” for the name attribute. You would add some code to parse the name into first name and last name, and then store the two components separately. You might start with something like this:

class Hero(object):
    def __init__(self, **kwargs):
        self.set_name(kwargs['name'])

    def set_name(self, name):
        self.name = name
        self.firstname, self.lastname = self.name.split(' ', 2)

if '__main__' == __name__:
    superman = Hero(name='Kal El')
    print superman.name
    print superman.firstname
    superman.name = 'Clark Kent'
    print superman.name
    print superman.firstname

# Kal El
# Kal
# Clark Kent
# Kal

The problem is that the simple assignment no longer works. Writing “superman.name = ‘Clark Kent'” no longer does what you expect; it only changes his name but does not change his firstname. Instead, you would need to write “superman.set_name(‘Clark Kent’)” which is painful; it requires you to hunt through your whole program and recode all occurrences of “superman.name =”.

This is where Python’s @property decorator comes in. It gives you a straightforward way to add behavior to the setter for the name attribute, so that you can still use “superman.name =” throughout your program.

class Hero(object):
    def __init__(self, **kwargs):
        self.name = kwargs['name']

    @property
    def name(self):
        return '%s %s' % (self.firstname, self.lastname)

    @name.setter
    def name(self, name):
        self.firstname, self.lastname = name.split(' ', 2)

if '__main__' == __name__:
    superman = Hero(name='Kal El')
    print superman.name
    print superman.firstname
    superman.name = 'Clark Kent'
    print superman.name
    print superman.firstname

# Kal El
# Kal
# Clark Kent
# Clark

Voila! Now the Hero class actually stores the firstname and the lastname while providing the illusion that it still has a simple attribute “name”. The @property decorator makes the syntax “superman.name” keep working to get the value of the name property. The @name.setter decorator, makes the syntax “superman.name =…” work to change the value of the hero’s name.

For more information on Python descriptors, see IBM’s excellent article, Introduction to Python descriptors.

Software

Recent Posts

  • Stretching a Photo April 21, 2025
  • There are Elephants in the Room April 10, 2025
  • Let’s Eliminate Real WFA April 1, 2025
  • Thumb Wrist Neck Waist Height March 18, 2025
  • Avoid Targeted Advertisements February 5, 2025

About Art Zemon

Omni-curious geek. Husband. Father. Airplane builder & pilot. Bicyclist. Photographer. Computer engineer.

Categories

  • Aviation (261)
    • Bede BD-4C (174)
    • Soaring (5)
  • Bicycling (37)
    • St. Louis to Atlanta (8)
    • St. Peters to Minneapolis (18)
  • Business (48)
  • Cabbages & Kings (24)
  • Communicating (37)
  • Ecology (21)
  • Economy (8)
  • Family (35)
  • Finding the Good (43)
  • Fun (188)
    • Six Word Stories (8)
  • Gardening (5)
  • Genealogy (5)
  • Government (35)
  • Health (67)
  • Judaism (10)
  • Men (12)
  • Mideast (5)
  • Movies (8)
  • Philosophy (15)
  • Photography (27)
  • Rants & Raves (103)
  • Recommendations (35)
  • Safety (37)
  • Science (22)
    • Biology (7)
    • Physics (7)
    • Pyschology (3)
  • Technology (195)
    • eBooks (7)
    • Internet (66)
    • Software (63)
    • VOIP (5)
  • Travel (43)
  • Tzedakah (12)
  • Women (5)

You Will Also Like

  • Art Zemon's Genealogy
  • Art Zemon's Photos
  • Mastodon @babka.social
  • Mastodon @raphus.social

Search

#DonorForLife

6 gallon blood donor badge
#DonorForLife - Give Blood - Save Lives

Archives

Copyright © 2025 · Daily Dish Pro Theme on Genesis Framework · WordPress · Log in