In [17]:
# huge topic. this is the basics
# classes "encapsulate" state and behavior
# in other words variables and functions (called methods).
# objects or instances of a class can use these variables
# to store per-object state, and the methods can access that
# per-object state.
# classes form a hierarchy.
# each class is a "subclass" of one other class, which is
# called its "superclass". The base class--one with no superclass,
# is called "object".
# (there is an old style of defining classes in Python 2 which I
# will not cover as it is generally considered bad practice to use it)
# by convention, class names are in capitalized camel case
# Here is the simplest class:
class EmptyClass(object):
pass
In [18]:
# to make an instance, call the class's "constructor". it is named after
# the class. The default constructor does nothing, so it works with our
# EmptyClass:
EmptyClass()
Out[18]:
In [19]:
# let's create a class with a method. All methods accept at least one argument;
# the first argument is called "self" and refers to whatever instance the method
# is called on.
class SimpleClass(object):
def hello(self):
return 'Hello'
# when you call the method, instead of passing an instance to it, you dereference it
# from an expression returning the instance, and you don't have to pass "self" to it.
o = SimpleClass()
o.hello()
Out[19]:
In [20]:
# a method that takes arguments takes them after "self"
class SimpleClass(object):
def hello(self, who='world'):
return 'Hello, %s.' % who
o = SimpleClass()
o.hello('everyone')
Out[20]:
In [21]:
# "self" can have properties set on it, which are per-instance
a = SimpleClass()
b = SimpleClass()
a.name = 'Joe'
class Thing(object):
pass
o = Thing()
o.something = 3
o.bar = 8
o
Out[21]:
In [22]:
# only classes can have their attributes set, and not, say, dicts
d = { 'one': 1, 'two': 2 }
d.name = 'Joe'
In [23]:
# inside methods, properties belong to "self"
class SimpleClass(object):
def hello(self):
return 'Hello, %s.' % self.name
joe = SimpleClass()
bethany = SimpleClass()
joe.name = 'Joe'
bethany.name = 'Bethany'
joe.hello(), bethany.hello()
Out[23]:
In [24]:
# methods can set properties
class SimpleClass(object):
def hello(self):
msg = 'Hello, %s.' % self.name
self.name = 'person I already said hello to'
return msg
joe = SimpleClass()
joe.name = 'Joe'
joe.hello()
Out[24]:
In [25]:
joe.hello()
Out[25]:
In [26]:
# each class has a special method called __init__ that is called when you construct an instance
class SimpleClass(object):
def __init__(self, name):
self.name = name
def hello(self):
return 'Hello, %s.' % self.name
joe = SimpleClass('Joe')
joe.hello()
Out[26]:
In [27]:
# methods can call each other using "self"
class SimpleClass(object):
def __init__(self, name):
self.name = name
def hello(self):
return 'Hello, %s.' % self.name
def say_hello(self):
print self.hello()
return 5
SimpleClass('Joe').say_hello()
Out[27]:
In [28]:
# you can "subclass" a class. the subclass will "inherit" methods from its "superclass"
# and you can "override" methods.
class SimpleSubclass(SimpleClass):
def hello(self):
return 'Oh hai %s.' % self.name
SimpleSubclass('Joe').say_hello()
Out[28]:
In [29]:
# be careful when overriding __init__, as the superclass's __init__ is not automatically called
class SimpleSubclass(SimpleClass):
def __init__(self, name, greeting):
self.greeting = greeting
def hello(self):
return '%s, %s.' % (self.greeting, self.name)
# this will not work
SimpleSubclass('Joe', 'Hi there').say_hello()
In [30]:
# there is a very specific idiom that must be used to call a superclass constructor
class SimpleSubclass(SimpleClass):
def __init__(self, name, greeting):
super(SimpleSubclass, self).__init__(name)
self.greeting = greeting
def hello(self):
return '%s, %s.' % (self.greeting, self.name)
SimpleSubclass('Joe', 'Greetings').say_hello()
Out[30]:
In [31]:
# you can also call any other superclass method the same way
class SimpleSubclass(SimpleClass):
def __init__(self, name, greeting):
super(SimpleSubclass, self).__init__(name)
self.greeting = greeting
def hello(self):
return '%s, %s.' % (self.greeting, self.name)
def say_hello(self):
super(SimpleSubclass, self).say_hello()
return 7
SimpleSubclass('Joe', 'Greetings').say_hello()
Out[31]:
In [32]:
# remember, once we create a class we can set its properties and call its methods
# and it will keep track of its properties as they change
o = SimpleSubclass('Joe','Greetings')
o.say_hello()
Out[32]:
In [33]:
o.name = 'everyone'
o.say_hello()
Out[33]:
In [34]:
o.greeting = 'Howdy'
o.say_hello()
Out[34]:
In [35]:
# you can set properties that are never used in any methods and that works too:
o.foobar = 3
o.say_hello()
Out[35]:
In [36]:
o.foobar
Out[36]: