forked from katenevin/python-crash-course
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclasses.py
More file actions
executable file
·105 lines (84 loc) · 3.06 KB
/
classes.py
File metadata and controls
executable file
·105 lines (84 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import random
# the simplest class you should define is a simple subclass of the base object that does nothing.
class NoOp(object):
pass
# you can also do this, but you very rarely want to:
class Objectless:
pass
# we can define a number of methods on a class.
class Animal(object):
# the __init__ method is an important one. Define this to do all your setup steps.
def __init__(self, name, legs=None, sound='quelp'):
if legs is None:
legs = random.choice(range(3, 101))
self.name = name
self.legs = legs
self.sound = sound
# an instance method is called on an instance of the class on which it is defined.
def speak(self):
# `self' is always the first argument of an instance method. This refers to the instance
# on which the method is called.
return self.sound
# a class method is called on the class itself and can be overridden by subclasses.
@classmethod
def can_fly(cls):
return False
# a static method is called using the class, but it does not get the class as an argument
# (the class is irrelevant to the method). All animals need love.
@staticmethod
def needs_love():
return True
# a property is a function that can be referenced as an attribute.
@property
def is_biped(self):
return self.legs == 2
class Bird(Animal):
def __init__(self, name, sound='tweet'):
super(Bird, self).__init__(name, 2, sound)
# because birds generally fly, we'll override the classmethod inherited from `Animal'.
@classmethod
def can_fly(cls):
# in general, birds can fly. (Flightless subclasses should override this.)
return True
class Ostrich(Bird):
def __init__(self, name):
super(Ostrich, self).__init__(name, None)
@classmethod
def can_fly(cls):
return False
# this is not really how you'd use this. I'm taking the joke too far.
def __call__(self):
raise NotImplementedError('An ostrich has no sound, so we cannot call it')
animal = Animal('Alice')
bird = Bird('Bob')
ostrich = Ostrich('Lewis')
assert Animal.can_fly() != Bird.can_fly()
assert Animal.needs_love() == Bird.needs_love()
assert Ostrich.can_fly() != Bird.can_fly()
assert ostrich.is_biped
assert bird.is_biped
assert not animal.is_biped
assert animal.sound == 'quelp'
class MathOperation(object):
def __init__(self, op, arg1, arg2):
self.op = op
self.arg1 = arg1
self.arg2 = arg2
def __call__(self):
if isinstance(self.arg1, MathOperation):
arg1 = self.arg1()
else:
arg1 = self.arg1
if isinstance(self.arg2, MathOperation):
arg2 = self.arg2()
else:
arg2 = self.arg2
return self.op(arg1, arg2)
from operator import add, sub
add_5_4 = MathOperation(add, 5, 4)
sub_5_4 = MathOperation(sub, 5, 4)
# here, we can create an operation tree that's computed at run-time
compound_add = MathOperation(add, add_5_4, sub_5_4)
assert add_5_4() == 5 + 4
assert sub_5_4() == 5 - 4
assert compound_add() == 10