Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

  




 

 

Chapter 25. Properties and Descriptors

Python provides some advanced control over an object's attributes. In the section called “Attribute Handling Special Method Names” we explicitly separated attribute and instance variable. The default rule is that an attribute name gives us access to an instance variable.

  • An attribute is a name that appears after an object name. For example, someObj.name.

  • An instance variable is a name in the __dict__ of an object.

When we say someObj.name, the default behavior is effectively someObj.__dict__['name']. However, we can alter this by making the name into a property or associating the name with a descriptor object.

There are several ways that we can tap into Python's internal mechanisms for getting and setting attribute values.

  • The most accessible technique is to use the property function to define get, set and delete methods associated with an attribute name. The property function builds descriptors for you. We'll look at this in the section called “Properties”.

  • A slightly less accessible, but more extensible and reusable technique is to define descriptor classes yourself. This allows you considerable flexibility. You do this by creating a class which defines get, set and delete methods, and you associate your descriptor class with an attribute name. We'll look at this in the section called “Descriptors”.

  • You can tap into Python's low-level special methods for attribute access. This is covered in the section called “Attribute Handling Special Method Names”.

Semantics of Attributes

Fundamentally, an object encapsulates data and processing via it's instance variables and method functions. Because of this encapsulation, we can think of a class definition as providing a interface definition and an implementation that fits the defined interface. The method names and public instance variables which begin with _ are treated as part of the private implementation of the class; the remaming elements form the public interface.

In Python, this distinction between interface and implementation is not heavily emphasized in the syntax, since it can often lead to wordy, complex programs. Most will-designed classes, however, tend to have a set of interface methods that form the interface for collaborating with objects of that class.

There are several commonly-used design patterns for an object's interface.

  • Getters and Setters. We can encapsulate each instance variable with method functions that get and set the value of that instance variable. To be sure that the instace variables aren't accessed except via the method functions, we make each instance variable private, using _ as the first character of the variable name. When we do this, each access to an attribute of the object is via an explicit function: anObject.setPrice( someValue ); anObject.getValue().

  • Properties. We can bind getter, setter (and deleter) functions with an attribute name, using the built-in property function. When we do this, each reference to an attribute looks like simple, direct access, but invokes the appropriate function of the object. For example, anObject.price= someValue; anObject.value.

  • Descriptors. We can bind getter, setter (and deleter) functions into a separate class. We then assign an object of this class to the attribute name. When we do this, each reference to an attribute looks like simple, direct access, but invokes an appropriate function of the Descriptor object. For example, anObject.price= someValue; anObject.value.

The Getter and Setter design pattern is does not have a Pythonic look. This design is common in C++; it is required in Java. Python programmers find the use of getter and setter functions to be wordy and prefer to access attributes directly.


 
 
  Published under the terms of the Open Publication License Design by Interspire