object
(or an instance of an object
)object
s encapsulate both data (variables/attributes) and functionality (methods)object
s define "types" or class
s, instances are "items"object
instances have a concept of self
** Enough talk, more code **
from IPython.display import display
class Thing:
pass
this = Thing()
that = Thing()
display(Thing,this, that)
__main__.Thing
<__main__.Thing at 0x7f8211652358>
<__main__.Thing at 0x7f8211652320>
This Thing
isn't particularly useful, so we can give it universal attributes (class_variable
)
class Thing(object):
class_variable = 'inner class variable available to all instances'
this = Thing()
that = Thing()
display(this,that)
display(this.class_variable, that.class_variable)
<__main__.Thing at 0x7f8211652ac8>
<__main__.Thing at 0x7f8211652a90>
'inner class variable available to all instances'
'inner class variable available to all instances'
that.class_variable = 'but you can change instance variables (this is terrible practice)'
display(this.class_variable, that.class_variable)
'inner class variable available to all instances'
'but you can change instance variables (this is terrible practice)'
class Thing(object):
class_variable = 'inner class variable available to all instances'
def set_class_variable(self, value):
self.class_variable = value
def get_class_variable(self):
return self.class_variable
this = Thing()
that = Thing()
that.set_class_variable('using getters and setters is better')
display(this.get_class_variable(), that.get_class_variable())
'inner class variable available to all instances'
'using getters and setters is better'
thon = Thing()
thon.class_variable='but we can still mess with things, which is bad news'
display(thon.class_variable)
'but we can still mess with things, which is bad news'
class Thing(object):
__private_class_variable = 'private var'
@property
def class_variable(self):
return self.__private_class_variable
@class_variable.setter
def class_variable(self, value):
self.__private_class_variable = value
this = Thing()
that = Thing()
that.class_variable='properties are even nicer, but whats the point?'
display(this.class_variable, that.class_variable)
'private var'
'properties are even nicer, but whats the point?'
class Thing(object):
__private_class_variable = 'var that must always be lower case'
@property
def class_variable(self):
return self.__private_class_variable
@class_variable.setter
def class_variable(self, value):
self.__private_class_variable = value.lower()
this = Thing()
that = Thing()
that.class_variable='We can EnForce Input ValIDation'
display(this.class_variable, that.class_variable)
'var that must always be lower case'
'we can enforce input validation'
class Greeter(object):
_greet_prefix = 'Hello there'
def __init__(self, greetee=None):
self.greetee = greetee
def wave(self):
if self.greetee is not None:
greeting = '{prefix}, {greetee}!'.format(
prefix = self._greet_prefix,
greetee = self.greetee
)
else:
greeting = '{prefix}!'.format(prefix = self._greet_prefix)
return greeting
a = Greeter()
b = Greeter("Code Coop")
display(a.wave(),b.wave())
'Hello there!'
'Hello there, Code Coop!'
class Person:
def __init__(self, name):
self.name = name
def say_hi(self):
print('Hello, my name is {name}'.format(name=self.name))
p = Person('Bob')
p.say_hi()
Hello, my name is Bob
class Adult(Person):
def vote_for(self, party):
print('{name} voted for {party}'.format(name=self.name,
party=party))
a = Adult('Alice')
a.say_hi()
a.vote_for('The Monster Raving Loony Party')
Hello, my name is Alice Alice voted for The Monster Raving Loony Party
p.vote_for('The Peoples Front of Judea')
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-14-0400bd571bb8> in <module>() ----> 1 p.vote_for('The Peoples Front of Judea') AttributeError: 'Person' object has no attribute 'vote_for'
interfaces
¶class Person(object):
def __init__(self, name):
self.name = name
def say_hi(self):
print('Hello, my name is {name}'.format(name=self.name))
# aka Abstract Method
def pay_tab(self):
raise NotImplementedError
def __cmp__(self, other):
return self.name > other.name
class Supervisor(Person):
def pay_tab(self):
print("Here you go! Keep the change!")
def say_hi(self):
print('Hello there youngun\', did you read my recent paper?')
class GradStudent(Person):
def pay_tab(self):
print("Can I owe you a tenner or do the dishes?")
people = [GradStudent('Alice'),
Supervisor('Jane'),
GradStudent('Claire'),
Person('Bob')
]
sorted(people)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-34-ce4488e07767> in <module>() 31 Person('Bob') 32 ] ---> 33 sorted(people) TypeError: unorderable types: Supervisor() < GradStudent()
for person in people:
try:
person.say_hi()
person.pay_tab()
except NotImplementedError:
print('This person doesn\'t have a pay_tab method yet!')
print('----')
Hello, my name is Alice Can I owe you a tenner or do the dishes? ---- Hello there youngun', did you read my recent paper? Here you go! Keep the change! ---- Hello, my name is Claire Can I owe you a tenner or do the dishes? ---- Hello, my name is Bob This person doesn't have a pay_tab method yet! ----
class Supervisor(Person):
def pay_tab(self):
print("Here you go! Keep the change!")
def say_hi(self):
super(Supervisor,self).say_hi()
print("I'm a Doctor don't you know")
people = [GradStudent('Alice'),
Supervisor('Jane'),
GradStudent('Claire'),
Person('Bob')
]
for person in people:
person.say_hi()
person.pay_tab()
print('----')
Hello, my name is Alice Can I owe you a tenner or do the dishes? ---- Hello, my name is Jane I'm a Doctor don't you know Here you go! Keep the change! ---- Hello, my name is Claire Can I owe you a tenner or do the dishes? ---- Hello, my name is Bob
--------------------------------------------------------------------------- NotImplementedError Traceback (most recent call last) <ipython-input-28-8b0b8657b710> in <module>() 2 for person in people: 3 person.say_hi() ----> 4 person.pay_tab() 5 print('----') <ipython-input-24-b022f35052b9> in pay_tab(self) 8 # aka Abstract Method 9 def pay_tab(self): ---> 10 raise NotImplementedError 11 12 class Supervisor(Person): NotImplementedError:
def add_ones_p(l):
new_list = []
for x in l:
new_list.append(x+1)
return new_list
def add_ones_f(l):
return list(map(lambda x:x+1, l))
display(
add_ones_p(range(5)),
add_ones_f(range(5))
)
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
%%timeit
add_ones_p(range(5))
840 ns ± 5.08 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%%timeit
add_ones_f(range(5))
1.34 µs ± 18.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
def imperative_countdown(i):
while i > 0:
print(i)
i = i - 1
print("Done!")
def recursive_countdown(i):
if i > 0:
try:
recursive_countdown(i-1)
except RecursionError:
print('Fucked on {}'.format(i))
else:
print("Done!")
imperative_countdown(10)
recursive_countdown(1000000000)
10 9 8 7 6 5 4 3 2 1 Done! Fucked on 999998028
1000000000 - 999998028
1972