layout: post title: "Python Concepts: Part None" date: 2014-09-20 17:30:00 +0100 comments: true
Let's learn about nothing. More particularly, let's learnt about python's concept of representing nothing, None
. This is the most nothingest concept of nothing as well - for example, zero is nothing, but it's also a number, so it still has some information. Other names for nothing from other programming languages include null
, nil
, or Nothing
.
I'm writing this post in IPython. If you want to follow along at home, get your IPython console started by typing ipython
at the command prompt. Didn't work? Install it. Bam.
Now, let's start. Let's see what happens if ask for nothing:
In [1]:
None
No output - makes sense. Let's try outputting it to screen though:
In [2]:
print None
Aha, we get some output. print
turns its input into a string so it can be output - and the str
ing output of None
is 'None'
. Let's check that str
ing representation:
In [3]:
str(None)
Out[3]:
Now, since we didn't use print, the output comes from the IPython prompt, with an "Out" marker to indicate that. IPython takes the expression you typed in, evaluates it, and displays the result as a prompt - unless the result is None
, when it displays nothing! And you guessed it, input 1 evaluated to None
, and so did input 2 (print
actually can't even return anything).
So if we print again, there is no output prompt, since the print statement evaluates to nothing. Let's try print
ing the str
ing of None
:
In [4]:
print str(None)
Brilliant.
Anyway, the string "None"
is something, and we're here to investigate nothing. Let's use an IPython feature to find out more about it:
In [5]:
None?
{% highlight ipy %}
Type: NoneType
String form: None
Namespace: Python builtin
Docstring:
Intriguing. None
has a type - the NoneType
. In fact, every object in python has a type, which is like a class
in other languages, except it extends to builtin things as well.
The String Form there - that's what you get when you pass None
to str
as we've seen.
Namespace is 'Python builtin' - which means, surprise surprise, it's built-in to Python.
There's no docstring - this is a way of adding documentation to objects in Python for users to access. Let's check for a docstring on another object we know about:
In [6]:
str?
{% highlight ipy %} Type: type String form: <type 'str'> Namespace: Python builtin Docstring: str(object='') -> string
Return a nice string representation of the object. If the argument is a string, the return value is the same object. {% endhighlight %}
Ah, str
's docstring is much more instructive - and it tells us how to do what we did on line 3!
But its type is type? This means we can make fresh str
objects by calling the type:
In [7]:
str()
Out[7]:
And tada, a blank str
ing appears.
Can we do that with the NoneType
I wonder?
In [8]:
NoneType()
Uh-oh. Looks like we don't actually have NoneType
available in our current namespace - just None
. But luckily, we can ask for the type of None
, store it in a variable, and call that:
In [9]:
type(None)
Out[9]:
In [10]:
local_none_type = type(None)
In [11]:
local_none_type()
Dang. We can have a handle on the NoneType
type, but we can't make any more of it. This is actually a special rule for the NoneType
... Does it mean there is only ever one None
?
In [12]:
a = None
In [13]:
b = None
In [14]:
a == b
Out[14]:
Well, they're equal, that's a start. But can we check that a
and b
are exactly the same thing?
In [15]:
a is b
Out[15]:
Yes indeed they are. So there is only ever one None
, and we can never make any more of it. That's useful to know - write it down in your copy book now.
Let's have a break with a quote on nothing:
Nothing proceeds from nothingness, as also nothing passes away into non-existence.
-- Marcus Aurelius, Meditations, IV, 4
Let's continue; I wonder if None
can be checked against:
In [16]:
if None: print "Yes, none."
Oh, nothing happened. Let's see what happens if we go the other way:
In [17]:
if not None: print "Yes, not none."
Aha! So None
is never True
, and always False
? Let's just check that by turning it into a bool
ean:
In [18]:
bool(None)
Out[18]:
Exactly.
That explains why our if
statement worked that way - None
gets turned into False
when we test it as a bool
ean.
Let's try doing some more day-to-day things with None
.
In [19]:
None + None
In [20]:
None - None
In [21]:
None + 0
So, you can't really do anything. Makes sense that you do (nearly) nothing with nothing.
Let's check its dir
ectory of methods though - maybe it has something it hasn't told us yet.
In [22]:
dir(None)
Out[22]:
Wow, that's a lot of things! How many things?
In [23]:
len(dir(None))
Out[23]:
Wow, there are actually 15 things that None
can do!?
Let's try from the top...
In [24]:
None.__class__
Out[24]:
NoneType
again? I thought we already got that guy with type
! Is that the same NoneType
really?
In [25]:
type(None) is None.__class__
Out[25]:
Okay, that's boring - just another way to get ahold of that __class__
it looks like.
Let's check the next one - __delattr__
.
In [26]:
None.__delattr__
Out[26]:
Okay, it's a method-wrapper. Guess that means it's like a method. Let's try calling it.
In [27]:
None.__delattr__()
Okay, you want an argument? I'll give you an argument!
In [28]:
None.__delattr__("argument")
Oh, you want an argument that's the name of an attribute? Why didn't you say? We already know the name of an attribute that we don't need - __class__
is something we can get by calling type
- so let's try saving some space by getting rid of that:
In [29]:
None.__delattr__("__class__")
Well that's annoying, but I guess it's okay for python to have some protection over such built-in features. For all we know, type
might need the __class__
attribute to be there to work, right?
I give up, let's try the next one.
In [30]:
None.__doc__
Oh great, nothing. This is actually the attribute that stores an object's docstring though - and as we saw earlier, None
has no docstring.
Let's check by getting the str
docstring in the same way:
In [31]:
str.__doc__
Out[31]:
Yup, that's the string, although the new-line characters have been displayed as \\n
. Next!
In [32]:
None.__format__
Out[32]:
In [33]:
None.__format__()
In [34]:
None.__format__(None)
Okay, let's pass in an empty str.
In [35]:
None.__format__("")
Out[35]:
In [36]:
None.__getattribute__()
Let's try giving it the name of an attribute...
In [37]:
None.__getattribute__("__class__")
Out[37]:
Wow, we just discovered that the 'dot' operator really just calls the __getattribute__
method of the object! So you can get any attribute that way? Let's try getting them all!
In [38]:
for name in dir(None):
print name, " -> ", None.__getattribute__(name)
Wow, that saved some work, checking what they are and where they are from! Most seem to be part of the NoneType
object, but some are from object
or type
. Weird!
Wait, is None
an object
?
In [39]:
isinstance(None, object)
Out[39]:
Apparently so! What else is an object
?
In [40]:
isinstance(object, object)
Out[40]:
In [41]:
isinstance(type(None), object)
Out[41]:
In [42]:
isinstance(type, object)
Out[42]:
Well, I heard python is object-oriented, but it seems oriented towards making everything an object.
So what does that mean? Does object have some stuff on it that you can do anywhere or something?
In [43]:
dir(object)
Out[43]:
In [44]:
len(dir(object))
Out[44]:
Holy smokes, that's like the same list that None
has! Wait, is it exactly the same list?
In [45]:
dir(object) == dir(None)
Out[45]:
Yes indeed! Aww wait, this means we learnt nothing interesting about None
- it only has all the attributes that every other object
has. So maybe it really doesn't do anything!
But we've learnt some valuable lessons:
None
None
is NoneType
None
None
does nothing interestingNone
into a str
ing, it becomes 'None'
. If you turn None
into a bool
ean, it becomes False
.That's all we have time for in this blog post! Next time: True
and False
enter the picture in full focus.