Created
February 22, 2012 15:42
-
-
Save olooney/1885603 to your computer and use it in GitHub Desktop.
examples of python class customization, generic descriptors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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