Skip to content

Instantly share code, notes, and snippets.

@olooney
Created February 22, 2012 15:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olooney/1885603 to your computer and use it in GitHub Desktop.
Save olooney/1885603 to your computer and use it in GitHub Desktop.
examples of python class customization, generic descriptors
import math
class Magnitude(object):
'''A descriptor that can be added to any N-dimensional point to provide a read/writable magnitude property.'''
def __init__(self, *attributes):
self.attributes = attributes
def __get__(self, instance, owner):
sum_of_squares = 0.0
for attr in self.attributes:
value = getattr(instance, attr, 0)
sum_of_squares += value * value
return math.sqrt(sum_of_squares)
def __set__(self, instance, new_magnitude):
current_magnitude = Magnitude.__get__(self, instance, instance.__class__)
if current_magnitude:
scale_factor = float(new_magnitude) / current_magnitude
for attr in self.attributes:
value = getattr(instance, attr, 0)
setattr(instance, attr, value * scale_factor)
else:
# can't scale a zero vector...
pass
class P2(object):
'''A 2D point class providing many examples of Python class customization.'''
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return 'P2({}, {})'.format(self.x, self.y)
def __unicode__(self):
return unicode(self.__str__())
def __repr__(self):
return self.__str__()
def __getitem__(self, index):
if index == 0 or index == 'x':
return self.x
elif index == 1 or index == 'y':
return self.y
else:
raise IndexError('point index out of range')
def __setitem__(self, index, value):
if index == 0 or index == 'x':
self.x = value
elif index == 1 or index == 'y':
self.y = value
else:
raise IndexError('point index out of range')
def __len__(self):
return 2
def __iter__(self):
yield self.x
yield self.y
def __complex__(self):
return complex(self.x, self.y)
def __add__(self, other):
return self.__class__(self.x + other.x, self.y + other.y)
magnitude = Magnitude('x', 'y')
p = P2(3,4)
print p
print p.magnitude
# normalize the vector
p.magnitude = 1
print p
p[0] = 4
p[1] = 3
print p
print 'length:', len(p)
x, y = p
print 'unpacked:', x, y
for v in p:
print v
if 4 in p: print '4 in p'
if 5 in p: print '5 in p'
print complex(p)
print p + P2(10, 10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment