Created
November 8, 2014 13:56
-
-
Save redhog/0150ca00590cd8467983 to your computer and use it in GitHub Desktop.
Some more about classes
This file contains hidden or 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
#### 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() |
This file contains hidden or 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
# 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() |
This file contains hidden or 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
# 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