A short Python class puzzle

PuzzleHere’s a short Python puzzle that I use in many of my on-site courses, which I have found to be useful and instructive: Given the following short snippet of Python, which letters will be printed, and in which order?

print("A")
class Person(object):
    print("B")
    def __init__(self, name):
        print("C")
        self.name = name
    print("D")
print("E")

p1 = Person('name1')
p2 = Person('name2')

Think about this for a little bit before looking at the answer, or executing it on your computer.

Let’s start with the answer, then:

A
B
D
E
C
C

Let’s go through these one by one, to understand what’s happening.

The initial “A” is printed because… well, because it’s the first line of the program. And in a Python program, the lines are executed in order — starting with the first, then the second, and so forth, until we reach the end.  So it shouldn’t come as a surprise that the “A” line is printed first.

But what is surprising to many people — indeed, the majority of people who take my courses — is that we next see “B” printed out.  They are almost always convinced that the “B” won’t be printed when the class is defined, but rather when… well, they’re really sure when “B” will be printed.

Part of the problem is that Python’s keywords “class” and “def” look very similar. The former defines a new class, and the latter defines a new function. And both start with a keyword, and take a block of code.  They should work the same, right?

Except that “class” and “def” actually work quite differently: The “def” keyword creates a new function, that’s true.  However, the body of the function doesn’t get executed right away. Instead, the function body is byte compiled, and we end up with a function object.

This means that so long as the function body doesn’t contain any syntax errors (including indentation errors), the function object will be created. Indeed, the following function will produce an error when run, but won’t cause a problem when being defined:

def foo():    asdfafsafasfsafavasdvadsvas

This is not at all the case for the “class” keyword, which creates a new class. And if we think about it a bit, it stands to reason that “class” cannot work this way. Consider this: Immediately after I’ve defined a class, the methods that I’ve defined are already available. This means that the “def” keyword inside of the class must have executed. And if “def” executed inside of a class, then everything else executes inside of a class, also.

Now, under most normal circumstances, you’re not going to be invoking “print” from within your class definition. Rather, you’ll be using “def” to define methods, and assignment to create class attributes. But both “def” and assignment need to execute if they are to create those methods and attributes! Their execution cannot wait until after the class is already defined.

I should also add that in Python, a class definition operates like a module: What would looks like an assignment to a global variable inside of the class definition is actually the creation of an attribute on the class (module) itself. And of course, the fact that the body of a class definition executes line by line makes it possible to use decorators such as @staticmethod and @property.

In short, “def” inside of a class definition creates a new function object, and then creates a class-level attribute with the same name as your function.

So, when you define a class, Python executes each line, in sequence, at the time of definition.  That’s why “B” is printed next.

Why is “C” not printed next? Because the body of a function isn’t executed when the function is defined. So when we define our __init__  method, “print” doesn’t run right away.  It does, however, run one time for each of the two instances of “Person” we create at the end of the program, which is why “C” is printed twice.

However, before “C”  is printed, the class definition still needs to finish running.  So we first see “D” (inside of the class definition), and then “E” (just after the class is defined).

Over the years, I’ve found that understanding what goes on inside of a class definition helps to understand many of the fundamental principles of Python, and how the language is implemented. At the same time, I’ve found that even in my advanced Python classes, a large number of developers don’t answer this puzzle correctly, which means that even if you work with Python for a long time, you might not have grasped the difference between “class” and “def”.

Data science + machine learning + Python course in Shanghai

Reuven teaching in ChinaData science is changing our lives in dramatic ways, and just about every company out there wants to take advantage of the insights that we can gain from analyzing our data — and then making predictions based on that analysis.

Python is a leading language (and some would say the leading language) for data scientists. So it shouldn’t come as a surprise that in addition to teaching intro and advanced Python courses around the world, I’m increasingly also teaching courses in how to use Python for data science and machine learning.  (Within the next few weeks, I expect to release a free e-mail course on how to use Pandas, an amazing Python library for manipulating data.   I’ve already discussed it on my mailing list, with more discussion of the subject to come in the future.)

Next month (i.e., February 2017), I’ll be teaching a three-day course in the subject in Shanghai, China.  The course will be in English (since my Chinese is not nearly good enough for giving lectures at this point), and will involve a lot of hands-on exercises, as well as lecture and discussion.  And lots of bad jokes, of course.

Here’s the advertisement (in Chinese); if you’re interested in attending, contact me or the marketing folks at Trig, the company bringing me to China:

http://mp.weixin.qq.com/s/kNwRpwEdhwqjL22e4TdgLA

Can’t make it to Shanghai? That’s OK; maybe I can come to your city/country to teach!  Just contact me at reuven@lerner.co.il, and we can chat about it in greater depth.

Announcing: Trainer Weekly, practical advice for technical trainers

Do you offer technical training?  Or are you just interested in becoming a trainer?

I’ve been doing technical training for several years now, and it has become the main thing that I do.  I love it, and encourage everyone to look into it as a potential career (or part of a career).

I’ve created an online Facebook group for trainers. I’m doing coaching for trainers. And most recently, I started “Trainer Weekly,” a free newsletter for people offering training. Every Monday, you’ll get a new piece of advice about th business, pedagogy, or logistics of training. How do you price things?  How do companies think about training? What sorts of courses can and should you offer?  What kinds of exercises should you give in class?

If this sounds interesting to you, then sign up for Trainer Weekly, and expect to get a new message from me every Monday.  If you have specific questions about training, then just drop me a line; I’ve already addressed a few topics that were requested by readers, and hope to address many more.

Free download: Cheat sheet for Python data structures

Get the Python data manipulations cheat sheet

Just about every day of every week, I teach Python. I teach not only in Israel, but also in Europe, China, and the US.  While I do teach newcomers to programming, the overwhelming majority of my students are experienced developers in another language — most often C, C++, Java, or C#.

For many of these people, I find that it’s hard to keep track of which data structure does what — when do you use lists vs. dicts vs. tuples vs. sets.  Moreover, it’s hard for them to remember the most common methods and operators we use on these data structures.

Perhaps the most common question I get is, “How do I add a new element to a dictionary?”  They’re often looking for an “append” method, and are surprised to find that one doesn’t exist.

That, and other questions, led me to create this  “cheat sheet for Python data structures.”  It’s not meant to be all-encompassing, but rather to provide some insights and reminders into the most common tasks you’ll want to do with lists, tuples, dicts, and sets.

My students have found this to be helpful — and I hope that it’ll be useful to other Python developers out there, as well!  Feedback is, of course, warmly welcome.

Get the Python data manipulations cheat sheet