include "../_i/1.h"; ?>
Thus far in Python we've been working with strings, numbers, lists, dictionaries, tuples... These are all types of objects in Python. Everything is an object, and every object has a type. Let's verify this:
>>> s = 'some string' >>> type(s) <type 'str'> >>> str <type 'str'> >>> type(s) is str True
So s we call an instance of the
str
type. Let's look at an instance of
the list
and bool
types:
>>> mylist = [1,2,3] >>> type(mylist) <type 'list'> >>> myboolean = False >>> type(myboolean) <type 'bool'>
Why does it matter what type an object (or instance) is? For one
thing, it determines what methods you can call on it. Last week we saw
that if you have a string instance s
, you can call
s.replace('a', 'b')
to replace all 'a's in the string
with 'b's. But if you have a list mylist
and you try to
call mylist.replace(...)
, you'll get an error. The
list
type has no replace
method, so list
instances don't either.
>>> mylist.replace('a', 'b') Traceback (most recent call last): File "", line 1, in AttributeError: 'list' object has no attribute 'replace'
str
, list
, dict
,
bool
, and tuple
are all built-in
types. But we can also define our own user-defined types,
which are called classes. Most of you have probably
seen classes before, in Java or PHP or Perl (sort of).
Let's say we're writing a blog engine. Clearly we'll need to work with blog posts. So we'll want a class to represent a blog post:
class BlogPost(object): """ A blog post with a title and content. """ def __init__(self, title, content=''): self.title = title self.content = content
The __init__ method is "magic": it's called whenever a new instance of your class is created. It's usually used for initialization, as we do here. (A "method" is just what we call a function when it belongs to a class).
>>> my_post = BlogPost('The Title') >>> my_post.title 'The Title' >>> my_post.content '' >>> my_post.content = "Some really long content.\n\nAnother paragraph." >>> print my_post.content Some really long content. Another paragraph.
So far our BlogPost objects are kind of... dead. They don't do anything. They can hold data (a title and some content), but they have no methods (besides __init__). Let's add one:
class BlogPost(object): def __init__(self, title, content=''): self.title = title self.content = content def get_first_paragraph(self): """ Return the first paragraph of this blog post's content. """ return self.content.split('\n\n')[0]
>>> my_post = BlogPost('The Title', "Some content.\n\n" ... "Another paragraph\n\n" ... "A third paragraph.") >>> print my_post.content Some content. Another paragraph. A third paragraph. >>> print my_post.get_first_paragraph() Some content.
Our BlogPost
class definition begins with the
line:
class BlogPost(object):
Our class inherits from the object
class. This means that, before we've written any further code, it
already has any methods defined on that class. In this
case, object
is a generic base class, a blank slate. Any
class you write which doesn't inherit from some other class should
inherit from object
. (You may see this referred to as a
"new-style" class; "old-style classes" inherit from nothing at all,
and are only for backwards-compatibility, they shouldn't be used in
new code).
Use inheritance to create more specialized types
of general classes. For instance, some blog posts are really nothing
but a link to some external URL with a bit of commentary. It may be
useful to have a specialized LinkPost
class for those
posts. LinkPost
s are still BlogPost
s too; if
we define new methods (or change existing methods)
on BlogPost
, we want LinkPost
to get those
changes automatically (we don't want to duplicate code and have to
change the same code two different places).
class LinkPost(BlogPost): " A subclass of BlogPost for external links. " def __init__(self, title, link, content=''): super(LinkPost, self).__init__(title, content) self.link = link def get_first_paragraph(self): first_para = super(LinkPost, self).get_first_paragraph() return "\n".join([first_para, self.link])
>>> my_link = LinkPost('Check this out', ... 'http://www.example.com', ... 'What a beautiful example URL.') >>> print my_link.get_first_paragraph() What a beautiful example URL. http://www.example.com
BlogPost
class so that it also has author
and date attributes.as_html
method to BlogPost
which
returns (as a string) a simple HTML representation of the blog post,
including all of its data attributes (title, author, date,
content).