Skip to content

Instantly share code, notes, and snippets.

@redhog
Created November 8, 2014 13:56
Show Gist options
  • Save redhog/0150ca00590cd8467983 to your computer and use it in GitHub Desktop.
Save redhog/0150ca00590cd8467983 to your computer and use it in GitHub Desktop.
Some more about classes
#### Sometimes you only have one of something, so no reason to make instances:
class X(object):
base = 13
@classmethod
def foo(cls, a, b):
return cls.base + a + b
class Y(X):
base = 14
print X.foo(1, 2)
print Y.foo(1, 2)
#### Or you have some things that are shared between all instances of a class:
class Item(object):
sum = 0.0
count = 0.0
def __init__(self, value):
self.value = value
type(self).sum += value
type(self).count += 1
@classmethod
def average(cls):
return cls.sum / cls.count
def strangeness(self):
return (self.value - self.average)**2
i1 = Item(3)
i2 = Item(4)
i3 = Item(47)
print i3.strangeness()
# Sometimes you want to imitate a built-in type, like a list, a dictionary or a number. This can all be done by implementing specially named methods:
class Powers(object):
def __init__(self, power):
self.power = power
def __getitem__(self, key):
return key ** self.power
squares = Power(2)
print squares[4] # squares now works like an infinite list of all possible squares...
class Phi(object):
def __init__(self, phi = 1.0, real = 0.0):
self.phi = phi
self.real = real
def clean(self):
if self.phi == 0.0:
return self.real
return self
def __repr__(self):
return "%s + %sphi" % (self.real, self.phi)
def __add__(self, other):
if not isinstance(other, Phi): other = Phi(phi=0.0, real = other)
return Phi(self.phi + other.phi, self.real + other.real).clean()
def __sub__(self, other):
if not isinstance(other, Phi): other = Phi(phi=0.0, real = other)
return Phi(self.phi - other.phi, self.real - other.real).clean()
print Phi()
print Phi() + 1
print Phi() + Phi()
print Phi() - 2
print Phi() - Phi()
# Just to tie together the lose ends of the type system. You probably should nopt use any of this, but it definitely helps understanding this to understand the more practical parts of it. Thing of the type system as a kind of algebra.
class MyType(type):
def __init__(self, name, bases, members):
for method_name, method in members:
if method_name.startswith('cls_'):
members[method_name] = classmethod(method)
type.__init__(self, name, bases, members)
class MyClass(object):
__metaclass__ = MyType
def cls_hello(cls):
# This method will be converted to a @classmethod by MyType:s __init__
print "hello"
class OtherClass(MyClass):
# This class inherits the metaclass of MyClass, we don't have to specify that again
def cls_foo(cls):
print "Fooooo!"
type(MyClass) == MyType
type(OtherClass) == MyType
isinstance(OtherClass, MyType) == True
isinstance(OtherClass, type) == True # MyType is a subclass of type
MyClass.cls_hello()
OtherClass.cls_foo()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment