Home arrow Python arrow Page 2 - More Object Orientation in Python

Types and Classes - Python

This article goes beyond the basics of object orientation in Python. It covers the interesting things you can do with new-style classes, including properties and attributes, as well as other useful information.

TABLE OF CONTENTS:
  1. More Object Orientation in Python
  2. Types and Classes
  3. Properties
  4. Methods: Instance, Class and Static
By: Peyton McCullough
Rating: starstarstarstarstar / 11
December 06, 2005

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

In Python, built-in types such as dictionaries are different from classes that you or I put together. Before Python 2.2, the differences were not incredibly overt, but they served as an annoyance. The biggest difference was that you could not subclass built-in types in your own classes. While differences still exist, these differences are now fewer in number and less severe since the introduction of some new features in Python 2.2. Now, you are free to subclass built-in types, and many other things have been introduced as well that we will discuss. Classes that utilize these new features are called “new-style” classes.

Let's build one of these new-style classes by subclassing the int type. Currently, if you create an int object and assign a decimal value, everything past the decimal point will be cut off:

>>> x = int ( 5.2 )
>>> x
5
>>> x = int ( 5.9 )
>>> x
5
>>> type ( x )
<type 'int'>

Let's say we wanted to subclass int and change this behavior, rounding the number to the closing integer. What was once impossible in Python is now easily done. We simply set int as the base class for our new class, and we do our magic in the __new__ method:

>>> class RoundInt ( int ):
 def __new__ ( cls, number ):
  number = round ( number )
  return int.__new__ ( cls, number )

Now, you may be wondering why we use __new__ rather than __init__. The answer is very simple: __new__ is responsible for returning an instance of the class. We have to round the given number before the number is returned, or it will be too late. You may also be wondering why we use the variable cls rather than self. This can be explained by this bit of code:

>>> class TestInt ( int ):
 def __new__ ( cls, number ):
  print cls
  return int.__new__ ( cls, number )
 def __init__ ( self, number ):
  print self

  
>>> x = TestInt ( 5 )
<class '__main__.TestInt'>
5

Of course, nothing is stopping you from using self rather than cls, just as nothing is stopping you from using this as opposed to self.

Instead of referencing int when we access its __new__ method, there is an alternative way to write our RoundInt class. We'll rewrite our class to use super:

>>> class RoundInt ( int ):
 def __new__ ( cls, number ):
  number = round ( number )
  return super ( RoundInt, cls ).__new__ ( cls, number )

Here's the result of our class:

>>> y = RoundInt ( 5.2 )
>>> y
5
>>> y = RoundInt ( 5.9 )
>>> y
6

We could also create a class based off int that accepts a sequences of numbers, adding them all together to get its value:

>>> class ListInt ( int ):
 def __new__ ( cls, sequence ):
  number = 0
  for value in sequence:
   number = number + value
  return super ( ListInt, cls ).__new__ ( cls, number )

Here is our new class in action:

>>> x = ListInt ( [ 1, 1 ] )
>>> x
2
>>> y = ListInt ( [ 10, 1, 5, 15, 7, 21, 18 ] )
>>> y
77

It's easy to see that this allows for some pretty unique and interesting things to be done with Python. Let's say that we want to subclass dict to take two arguments: a list of keys and a list of values. In __init__, these lists will be put together: one key to the one respective value. If none of these arguments are passed, then this special process is ignored. We use __init__ rather than __new__ because we want to work with the already initialized dictionary. Here's how it's done:

>>> class ListDict ( dict ):
 def __init__ ( self, keys = [], values = []):
  super ( ListDict, self ).__init__ ( self )
  counter = 0
  for key in keys:
   self.__setitem__ ( key, values [ counter ] )
   counter = counter + 1

Here's how our new class works:

>>> x = ListDict ( [ 'one', 'two', 'three' ], [ 'eins', 'zwei', 'drei' ] )
>>> x
{'three': 'drei', 'two': 'zwei', 'one': 'eins'}
>>> y = ListDict()
>>> y [ 'four' ] = 'vier'
>>> y
{'four': 'vier'}
>>> type ( x )
<class '__main__.ListDict'>
>>> type ( y )
<class '__main__.ListDict'>

Obviously, this new ability is a pretty big change to Python. The products of it can be quite interesting, as our two examples have shown. This change to the language allows you to create hybrids of built-in code and user-written code which better suit your application.



 
 
>>> More Python Articles          >>> More By Peyton McCullough
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PYTHON ARTICLES

- Python Big Data Company Gets DARPA Funding
- Python 32 Now Available
- Final Alpha for Python 3.2 is Released
- Python 3.1: String Formatting
- Python 3.1: Strings and Quotes
- Python 3.1: Programming Basics and Strings
- Tuples and Other Python Object Types
- The Dictionary Python Object Type
- String and List Python Object Types
- Introducing Python Object Types
- Mobile Programming using PyS60: Advanced UI ...
- Nested Functions in Python
- Python Parameters, Functions and Arguments
- Python Statements and Functions
- Statements and Iterators in Python

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: