Find file
Fetching contributors…
Cannot retrieve contributors at this time
205 lines (162 sloc) 6.14 KB
Want to try out the examples? Don't want to type them up yourself? Never worry, is a convenient Python module with all the class definitions
for the examples in the magic methods guide in it.
# FileObject class, demonstrating __init__ and __del__
from os.path import join
class FileObject:
"""Wrapper for file objects to make sure the file gets closed on deletion."""
def __init__(self, filepath="~", filename="sample.txt"):
# open a file filename in filepath in read and write mode
self.file = open(join(filepath, filename), "r+")
def __del__(self):
del self.file
# Word class, demonstrating __new__, comparisons
class Word(str):
"""Class for words, defining comparison based on word length."""
def __new__(cls, word):
# Note that we have to use __new__. This is because str is an immutable
# type, so we have to initialize it early (at creation)
if " " in word:
print "Value contains spaces. Truncating to first space."
word = word[:word.index(" ")] # Word is now all chars before first space
return str.__new__(cls, word)
def __gt__(self, other):
return len(self) > len(other)
def __lt__(self, other):
return len(self) < len(other)
def __ge__(self, other):
return len(self) >= len(other)
def __le__(self, other):
return len(self) <= len(other)
# AccessCounter class, demonstrating __setattr__, __getattr__, and __delattr__
class AccessCounter:
"""A class that contains a value and implements an access counter.
The counter increments each time the value is changed."""
def __init__(self, val):
self.__dict__["counter"] = 0
self.__dict__["value"] = val
def __setattr__(self, name, value):
if name == "value":
self.__dict__["counter"] += 1
self.__dict__["value"] = value
def __delattr__(self, name):
if name == "value":
self.__dict__["counter"] += 1
del self.__dict__["value"]
# FunctionalList class, demonstrating __len__, __getitem__, __setitem__, __delitem__,
# __iter__, and __reversed__
class FunctionalList:
"""A class wrapping a list with some extra functional magic, like head,
tail, init, last, drop, and take."""
def __init__(self, values=None):
if values is None:
self.values = []
self.values = values
def __len__(self):
return len(self.values)
def __getitem__(self, key):
# if key is of invalid type or value, the list values will raise the error
return self.values[key]
def __setitem__(self, key, value):
self.values[key] = value
def __delitem__(self, key):
del self.values[key]
def __iter__(self):
return iter(self.values)
def __reversed__(self):
return reversed(self.values)
def append(self, value):
def head(self):
# get the first element
return self.values[0]
def tail(self):
# get all elements after the first
return self.values[1:]
def init(self):
# get elements up to the last
return self.values[:-1]
def last(self):
# get last element
return self.values[-1]
def drop(self, n):
# get all elements except first n
return self.values[n:]
def take(self, n):
# get first n elements
return self.values[:n]
# Entity class demonstrating __call__
class Entity:
"""Class to represent an entity. Callable to update the entity"s position."""
def __init__(self, size, x, y):
self.x, self.y = x, y
self.size = size
def __call__(self, x, y):
"""Change the position of the entity."""
self.x, self.y = x, y
# snip...
# Wrapper class to close an object in a with statement
class Closer:
"""A context manager to automatically close an object with a close method
in a with statement."""
def __init__(self, obj):
self.obj = obj
def __enter__(self):
return self.obj # bound to target
def __exit__(self, exception_type, exception_val, trace):
except AttributeError: # obj isn"t closable
print "Not closable."
return True # exception handled successfully
# Classes to represent descriptors and their use
class Meter(object):
"""Descriptor for a meter."""
def __init__(self, value=0.0):
self.value = float(value)
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value = float(value)
class Foot(object):
"""Descriptor for a foot."""
def __get__(self, instance, owner):
return instance.meter * 3.2808
def __set__(self, instance, value):
instance.meter = float(value) / 3.2808
class Distance(object):
"""Class to represent distance holding two descriptors for feet and
meter = Meter()
foot = Foot()
# Class to demo fine-tuning pickling
import time
class Slate:
"""Class to store a string and a changelog, and forget its value when
def __init__(self, value):
self.value = value
self.last_change = time.asctime()
self.history = {}
def change(self, new_value):
# Change the value. Commit last value to history
self.history[self.last_change] = self.value
self.value = new_value
self.last_change = time.asctime()
def print_changes(self):
print "Changelog for Slate object:"
for k, v in self.history.items():
print "%s\t %s" % (k, v)
def __getstate__(self):
# Deliberately do not return self.value or self.last_change.
# We want to have a "blank slate" when we unpickle.
return self.history
def __setstate__(self, state):
# Make self.history = state and last_change and value undefined
self.history = state
self.value, self.last_change = None, None