Saturday, July 18, 2015

Python Variables

This issue is a little different. Instead of bringing you the best information out on the web, I'm bringing you some of the worst.

Python variables are actually easy to understand if you have the right mental model. Unfortunately, most people have the wrong model.

Bad Google Results

Python variables are a simple topic, but there is a huge amount of misinformation about this on the internet. If you do a search for 'python variables', most of the information you find is just plain wrong!

Let's look at some of the top search results ...

http://www.tutorialspoint.com/python/python_variable_types.htm

"Variables are nothing but reserved memory locations to store values. This means that when you create a variable you reserve some space in memory. Based on the data type of a variable, the interpreter allocates memory and decides what can be stored in the reserved memory"

This is wrong. Python variables do not allocate memory.

Let's look at another one ...

http://www.learnpython.org/en/Variables_and_Types

"Python is completely object oriented, and not "statically typed". You do not need to declare variables before using them, or declare their type. Every variable in Python is an object"

Yes and no. Yes, Python is object oriented. No, variables are not objects.

Let's try another one ...

https://en.wikibooks.org/wiki/Python_Programming/Variables_and_Strings

"A variable is something that holds a value that may change. In simplest terms, a variable is just a box that you can put stuff in. You can use variables to store all kinds of stuff, but for now, we are just going to look at storing numbers in variables"

Nope. Not even close.


One last try ...

http://www.python-course.eu/variables.php

"As the name implies, a variable is something which can change. A variable is a way of referring to a memory location used by a computer program. A variable is a symbolic name for this physical location. This memory location contains values, like numbers, text or more complicated types.  A variable can be seen as a container (or some say a pigeonhole) to store certain values"


Wrong again. Python variables are not pigeonholes, or shoeboxes, or any other kind of container. 

How Variables Work In A Compiled Language Like C

So why is everyone so wrong about this? It's because they are taking what they know about a compiled language like C or Java and trying to apply it to Python.

Let's take a variable declaration in C and break it down into its parts.

Type, Name, and Value

Here is a typical C declaration

int i = 42;

We start with a type

int

This tells the compiler 2 things

  1. How much memory is needed to store the data.
  2. What operations are allowed on the data.

Different data types require different amounts of memory storage. A character needs 1 byte, an integer needs 4 bytes, and so forth.

Next, we have a variable name

i

The compiler allocates 4 bytes of memory exclusively for this variable. No other variable can use this memory.

Finally, we assign a value

= 42

The integer value 42 is copied into the 4 bytes allocated for the variable i.

You can think of this as the "envelope/letter" model. The variable acts like an envelope and the data acts like a letter put inside the envelope.

This is a good model for C or Java, but if you try to apply it to Python you will be hopelessly confused.

Everything Is An Object

In Python, everything is an object. Python has 3 built-in functions for examining objects

  • type()
  • id()
  • dir()

type()

The type() function returns an object's type. Every object has a specific type.

>>> type(42)
<type 'int'>

This tells us 42 is an integer object.

id()

The id() function returns an object's ID number. Every object has a unique ID number.

>>> id(42)
15893832

The ID number of this integer object is 15893832. Notice that ID has nothing to do with the value, which is 42.

dir()

The dir() function returns a list of all the object's attributes.

>>> dir(42)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']

The integer object 42 is a true object with many built-in methods. It is much more than just a simple number.

So far, we've been operating directly on the object without creating any variables.

Objects can exist without variables. They do not depend on variables in any way.

How Variables Work In Python

Now we're ready to talk about variables.

First, let's look at the Python Language Reference. What does it say about variables?

https://docs.python.org/2/reference/simple_stmts.html?highlight=assignment#grammar-token-assignment_stmt

"Assignment statements are used to (re)bind names to values and to modify attributes or items of mutable objects"

A variable is a name bound to an object. Variables DO NOT create objects, nor do they allocate memory to hold objects. They simply give us a way to refer to objects by name.


For example

x = 42

says "we can refer to the integer object 42 by the name x ".

x = y = 42

says "we can refer to the integer object 42 by either the name x or the name y "

Any time we use a variable in our program, we are really referring to the object named by that variable.



Variables can refer to anything, not just numbers.

We can bind names to any type of object.

We can bind a name to a list object

my_list = [1,2,3]

We can bind a name to a function object

def my_function():
    pass


f = my_function

Then we can call the function through that name

f()

We can bind a name to a string object

greeting = 'hello'

A Word About del()

You cannot directly destroy a Python object. Using the del() function on a variable only deletes the name, not the object. Python deletes objects automatically when they are no longer needed.

Still Confused?

If you are still confused about this, watch this excellent video by Ned Batchelder
http://nedbatchelder.com/text/names1.html

No comments:

Post a Comment