Programming Python, Part II
The tutorial in last month's issue covered the basics of installing Python, running it and using it. Then, we moved on to building a basic blog in Python. The blog was extremely simple—only a Python list. We focused on the posts and built a Post class:
class Post(object):
def __init__(self, title, body):
self.set_title(title)
self.set_body(body)
def set_title(self, title):
self._title = title
def get_title(self):
return self._title
def set_body(self, body):
self._body = body
def get_body(self):
return self._body
def __repr__(self):
return "Blog Post: %s" % self.get_title()
In this follow-up article, let's focus on the blog itself and go further.
Now that we have the Post class, we can make the Blog class. An initial implementation may look like this:
class Blog(object):
def __init__(self):
self._posts = []
def add_post(self, post):
self._posts.append(post)
def get_posts(self):
return self._posts
We are using a list to maintain the posts, but the interface is totally abstract behind a set of methods in the Blog class. This has a huge advantage: tomorrow we could replace that simple list with an SQL back end, and the code that uses Blog will need few, if any, changes.
Notice that there's no way to delete a post. We could tamper with _posts directly, but as long as we do what the class was meant to do, we can't delete a post. That may be good or bad, but the important thing is that by defining a set of methods, we exposed the design of how the class should be used.
The method get_posts returns all the posts. When we are writing a new post, we don't want the whole world to be able to read it until it is finished. The posts need a new member that tell whether it is published. In Post's initalizator, __init__, we add the line:
self._published = False
That makes every new post private by default. To switch states, we add the methods:
def publish(self):
self._published = True
def hide(self):
self._published = False
def is_public(self):
return self._published
In these methods, I introduced a new kind of variable—the boolean. Booleans are simple; they can be true or false. Let's play with that a bit:
>>> cool = blog.Post("Cool", "Python is cool")
>>> cool.is_public()
False
>>> cool.publish()
>>> cool.is_public()
True
>>> cool.hide()
>>> cool.is_public()
False
>>>
If, when you run is_public, you get:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "blog.py", line 25, in is_public
return self._published
AttributeError: 'Post' object has no attribute
'_published'
That's because _published was not created, it can't be used, and is_public wants to use it. Understanding errors in your tools is important if you want to be a successful programmer.
In this short set of messages, the last line is the error itself. There are various types of errors, and this one is an AttributeError. A lot of important information is given in the traceback. A traceback is a list of “who called whom”, providing an idea of what was being executed when the error occurred.
The first line of the traceback doesn't give much information. It probably relates to the line we typed at the REPL. The second line tells that the error was in the file blog.py, on line 25, on the method is_public. Now we have the line that raised the problem.
This traceback is simple. In a real application, you would have methods that call methods that call methods and so on. In those cases, it is not uncommon to see tracebacks of 25 lines or more. I've seen tracebacks of more than 150 lines, but those were extreme cases in extreme conditions.
The next step is a modification to the Blog class to pick up only published posts. So, we add a new method:
def get_public_posts(self):
published_posts = []
for post in self._posts:
if port.is_public():
published_posts.append(post)
Python tries to be as readable as possible, but that method introduces too many new things, so it requires some careful explanations.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- New Products
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- Nice article, thanks for the
9 hours 10 min ago - I once had a better way I
14 hours 56 min ago - Not only you I too assumed
15 hours 14 min ago - another very interesting
17 hours 7 min ago - Reply to comment | Linux Journal
19 hours 43 sec ago - Reply to comment | Linux Journal
1 day 1 hour ago - Reply to comment | Linux Journal
1 day 2 hours ago - Favorite (and easily brute-forced) pw's
1 day 4 hours ago - Have you tried Boxen? It's a
1 day 9 hours ago - seo services in india
1 day 14 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
error?
cool = blog.Post("Cool", "Python is cool")
I can't get the above line to work. Is that correct?
error?
Were you using Emacs and following the instructions in part I? If so, the class "Post" will be part of the module "blog". If not, you must arrange for that yourself - the article explains.
If I understand correctly. I'm not a Python programmer. :)