User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the Python section within the Software Development category of DaniWeb, a massive community of 403,120 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,403 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Python advertiser: Programming Forums

Starting Python

Join Date: Jun 2005
Posts: 142
Reputation: G-Do is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 11
G-Do's Avatar
G-Do G-Do is offline Offline
Junior Poster

Re: Starting Python

  #26  
Aug 16th, 2005
While Python offers flexible container data structures, such as lists and dictionaries, it is occasionally helpful to create our own. Suppose, for example, that we wanted to create a data structure with two dictionaries: one for key-value pairs where len(key) is even, and one for key-value pairs where len(key) is odd. We would like to allow the Python builtins, such as str(), len(), container[key], etc, to access our objects in a meaningful way, and Python lets us do this via container-emulation methods:
import sys
# -- The Container class
class Container:
     # Instance variables:
     # self.even is a dictionary which stores key-value pairs
     # where the key has an even length
     # self.odd is a dictionary which stores key-value pairs
     # where the key has an odd length
     # Initialize new Container objects
     def __init__(self):
          self.even = dict(); self.odd = dict()
     # __len__() lets you use len() to evaluate this object
     def __len__(self):
          return len(self.even)+len(self.odd)
     # __repr__() lets you use str() to evaluate this object
     def __repr__(self):
          return str(self.even)+"\n"+str(self.odd)
     # __getitem__ allows evaluation of container[key]
     def __getitem__(self, key):
          if len(key)%2 == 0: return self.even[key]
          else: return self.odd[key]
     # __setitem__ allows assignment to container[key]
     def __setitem__(self, key, value):
          if len(key)%2 == 0: self.even[key] = value
          else: self.odd[key] = value
     # __delitem__ lets you use del container[key] to remove keys
     def __delitem__(self, key):
          if len(key)%2 == 0: del self.even[key]
          else: del self.odd[key]
     # __contains__ lets you use "key in container" boolean expressions
     def __contains__(self, key):
          return (key in self.even or key in self.odd)
     # __iter__ lets you iterate through the items via "for x in container"
     def __iter__(self):
          ret = []
          ret.extend(self.even.keys())
          ret.extend(self.odd.keys())
          return ret.__iter__()
# -- The main function (diagnostic)
def main(args):
    # __init__
    c = Container()
    # __setitem__
    print "Adding key-value pairs\n"
    c["Laverne"] = "Shirley"
    c["Ozzie"] = "Harriet"
    c["Abbott"] = "Costello"
    c["Carl"] = "Steve"
    # __len__
    print "The length of our container is", len(c), "\n"
    # __repr__
    print "One string representation is:\n", str(c), "\n"
    # __getitem__
    print "The partner of Abbott is", c["Abbott"], "\n"
    # __delitem__
    del c["Laverne"]
    print "We have just deleted the Laverne:Shirley key-value pair"
    print "The new length is", len(c)
    print "Now, the container looks like\n", str(c), "\n"
    # __contains__
    print "Is the key 'Batman' in our container?"
    if "Batman" in c: print c["Batman"]
    else: print "Sorry, Boy Wonder"
    print "Is the key 'Ozzie' in our container?"
    if "Ozzie" in c: print "Yes, and it is", c["Ozzie"], "\n"
    else: print "No Ozzies here", "\n"
    # __iter__
    print "Let's iterate through all available keys and their values"
    for x in c: print x, "\t", c[x]
# -- The following code executes upon program invocation
if __name__ == "__main__": main(sys.argv)
What this gives you is the freedom to define your own container data structures, and then use them just like you would use Python-supplied containers. Pretty snazzy!

The trick here is that you can define these functions any way you want. For example, your __repr__ method could always return "fish" regardless of the values of the object's instance variables - but that would be counter-intuitive, because programmers generally expect str() to return a string value that represents, at least in part, the internal state of the object. So beware!

Also, the __iter__ method I provided doesn't really build an iterator object - it just compiles a list of keys, then borrows the iterator from that. For more information on iterators and generators, see van Rossum's reference manual.
Vi veri veniversum vivus vici
Reply With Quote  
All times are GMT -4. The time now is 2:36 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC