Книга: Practical Programming, Fourth Edition
Назад: What Is a Type?
Дальше: How Python Tells You Something Went Wro ng

Variables and Computer Memory: Remembering Values

Like mathematicians, programmers frequently assign names to values so that they can use them later. A name that refers to a value is called a variable. In Python, variable names can use letters, digits, and the underscore symbol (but they can’t start with a digit). For example, X, species5618, and degrees_celsius are all allowed, but 777 isn’t (it would be confused with a number), and neither is no-way! (it contains punctuation). Variable names are case-sensitive, so ph and pH are two different names.

New variable is created by assigning it a value:

 >>>​​ ​​degrees_celsius​​ ​​=​​ ​​26.0

Variables are created by executing assignment statements

This statement is called an assignment statement; we say that degrees_celsius is assigned the value 26.0. That makes degrees_celsius refer to the value 26.0. You can use variables anywhere you can use values. Whenever Python sees a variable in an expression, it substitutes the value to which the variable refers:

 >>>​​ ​​degrees_celsius​​ ​​=​​ ​​26.0
 >>>​​ ​​degrees_celsius
 26.0
 >>>​​ ​​9​​ ​​/​​ ​​5​​ ​​*​​ ​​degrees_celsius​​ ​​+​​ ​​32
 78.80000000000001
 >>>​​ ​​degrees_celsius​​ ​​/​​ ​​degrees_celsius
 1.0

Variables are called variables because their values can vary as the program executes. You can assign a new value to a variable:

 >>>​​ ​​degrees_celsius​​ ​​=​​ ​​26.0
 >>>​​ ​​9​​ ​​/​​ ​​5​​ ​​*​​ ​​degrees_celsius​​ ​​+​​ ​​32
 78.80000000000001
 >>>​​ ​​degrees_celsius​​ ​​=​​ ​​0.0
 >>>​​ ​​9​​ ​​/​​ ​​5​​ ​​*​​ ​​degrees_celsius​​ ​​+​​ ​​32
 32.0

Assigning a value to a variable that already exists doesn’t create a second variable. Instead, the existing variable is reused, which means that the variable no longer refers to its old value.

Equal Sign Is Not Equality in Python!

icon indicating an aside

In mathematics, = means “the thing on the left is equal to the thing on the right.” In Python, it means something quite different. An assignment is not symmetric: x = 12 assigns the value 12 to variable x, but 12 = x results in an error. Because of this, never describe the statement x = 12 as “x equals 12.” Instead, read this as “x gets 12,” “x becomes 12” or “x is assigned 12.”

You can create other variables; this example calculates the difference between the boiling point of water and the temperature stored in degrees_celsius:

 >>>​​ ​​degrees_celsius​​ ​​=​​ ​​15.5
 >>>​​ ​​difference​​ ​​=​​ ​​100​​ ​​-​​ ​​degrees_celsius
 >>>​​ ​​difference
 84.5

Values, Variables, and Computer Memory

We’re going to develop a model of computer memory—a memory model—that will let you trace what happens when Python executes a Python program. This memory model will help you accurately predict and explain how Python executes code, a skill essential for becoming a proficient programmer.

Every location in the computer’s memory has a memory address, much like a street address that uniquely identifies a house on the street. We’re going to mark the memory addresses with an id prefix (short for identifier) so that they look different from integers: id1, id2, id3, and so on.

Here is how you draw the floating-point value 26.0 using the memory model:

Object

This image shows the value 26.0 at the memory address id1. We will always show the type of the value as well—in this case, float. We will refer to this box as an object: a value stored at a specific memory address with a defined type. During the execution of a program, every value that Python keeps track of is stored inside an object in computer memory.

In our memory model, a variable contains the memory address of the object it refers to. To make the image easier to interpret, draw arrows from variables to their corresponding objects.

Trace references

This is important, so let’s repeat it:

We use the following terminology:

Whenever Python needs to know which value degrees_celsius refers to, it looks at the object at the memory address that degrees_celsius contains. In this example, that memory address is id1, so Python will use the value at the memory address id1, which is 26.0.

Assignment Statement

Here is the general form of an assignment statement:

 variable = expression

The right side of the equal sign is called the RHS (“right-hand side”). The left side of the equal sign is called the LHS (“left-hand side”). The statement is executed as follows:

  1. Evaluate the expression on the RHS to produce a value. This value has a memory address.

  2. Store the memory address of the value in the variable on the LHS. Create a new variable if the name doesn’t already exist; otherwise, reuse the existing variable, replacing the value at the memory address it contains.

Consider this example:

 >>>​​ ​​degrees_celsius​​ ​​=​​ ​​26.0​​ ​​+​​ ​​5
 >>>​​ ​​degrees_celsius
 31.0

Here is how Python executes the statement degrees_celsius = 26.0 + 5:

  1. Evaluate the expression on the RHS: 26.0 + 5. The evaluation produces the value 31.0, which has a memory address. (Remember that Python stores all values in computer memory.)

  2. Make the variable on the LHS, degrees_celsius, refer to 31.0 by storing the memory address of 31.0 in degrees_celsius.

Reassigning to Variables

Consider this code:

 >>>​​ ​​difference​​ ​​=​​ ​​20
 >>>​​ ​​double​​ ​​=​​ ​​2​​ ​​*​​ ​​difference
 >>>​​ ​​double
 40
 >>>​​ ​​difference​​ ​​=​​ ​​5
 >>>​​ ​​double
 40

This demonstrates that assigning to a variable does not change any other variable. To trace this code, start by assigning the value 20 to the variable difference, and then assign the result of evaluating 2 * difference (40) to the variable double.

Next, assign the value 5 to the variable difference, but when you examine the value of double, it still refers to 40.

Here’s how it works according to the rules. The first statement, difference = 20, is executed as follows:

  1. Evaluate the expression on the RHS: 20. This produces the value 20, which you’ll put at memory address id1.

  2. Make the variable on the LHS, difference, refer to 20 by storing id1 in difference.

Here is the current state of the memory model. (Variable double has not yet been created because you have not yet executed the assignment to it.)

Trace step

The second statement, double = 2 * difference, is executed as follows:

  1. Evaluate the expression on the RHS: 2 * difference. As shown in the memory model, difference refers to the value 20, so this expression is equivalent to 2 * 20, which yields 40. Let’s pick the memory address id2 for the value 40.

  2. Make the variable on the LHS, double, refer to 40 by storing id2 in double.

Here is the current state of the memory model:

Trace step

When Python executes the third statement, double, it merely looks up the value that double refers to (40) and displays it.

The fourth statement, difference = 5, is executed as follows:

  1. Evaluate the expression on the RHS: 5. This produces the value 5, which we’ll put at the memory address id3.

  2. Make the variable on the LHS, difference, refer to 5 by storing id3 in difference.

Here is the current state of the memory model:

Trace step

The variable double still contains id2, so it still refers to 40. Neither variable refers to 20 anymore.

The fifth and last statement, double, merely looks up the value that double refers to, which is still 40, and displays it.

You can even use a variable on both sides of an assignment statement:

 >>>​​ ​​number​​ ​​=​​ ​​3
 >>>​​ ​​number
 3
 >>>​​ ​​number​​ ​​=​​ ​​2​​ ​​*​​ ​​number
 >>>​​ ​​number
 6
 >>>​​ ​​number​​ ​​=​​ ​​number​​ ​​*​​ ​​number
 >>>​​ ​​number
 36

We’ll now explain how Python executes this code, but won’t explicitly mention memory addresses. Trace this on a piece of paper while we describe what happens; make up your memory addresses as you do this.

Python executes the first statement, number = 3, as follows:

  1. Evaluate the expression on the RHS: 3. This one is easy to evaluate: 3 is produced.

  2. Make the variable on the LHS, number, refer to 3.

Python executes the following statement, number = 2 * number, as follows:

  1. Evaluate the expression on the RHS: 2 * number. number currently refers to 3, so this is equivalent to 2 * 3, and 6 is produced.

  2. Make the variable on the LHS, number, refer to 6.

Python executes the third statement, number = number * number, as follows:

  1. Evaluate the expression on the RHS: number * number. number currently refers to 6, so this is equivalent to 6 * 6, and 36 is produced.

  2. Make the variable on the LHS, number, refer to 36.

Augmented Assignment

In this example, the variable score appears on both sides of the assignment statement:

 >>>​​ ​​score​​ ​​=​​ ​​50
 >>>​​ ​​score
 50
 >>>​​ ​​score​​ ​​=​​ ​​score​​ ​​+​​ ​​20
 >>>​​ ​​score
 70

This pattern is so typical that Python provides a shorthand notation for this operation:

 >>>​​ ​​score​​ ​​=​​ ​​50
 >>>​​ ​​score
 50
 >>>​​ ​​score​​ ​​+=​​ ​​20
 >>>​​ ​​score
 70

An augmented assignment combines an assignment statement with an operator to make the statement more concise. An augmented assignment statement is executed as follows:

  1. Evaluate the expression on the RHS to produce a value.

  2. Apply the operator attached to the equal sign to the variable on the LHS and the value that was produced, resulting in another value. Store the memory address of that value in the variable on the LHS.

Note that the operator is applied after the expression on the right is evaluated:

 >>>​​ ​​d​​ ​​=​​ ​​2
 >>>​​ ​​d​​ ​​*=​​ ​​3​​ ​​+​​ ​​4
 >>>​​ ​​d
 14

All the operators (except for negation) in , have shorthand versions. For example, you can square a number by multiplying it by itself:

 >>>​​ ​​number​​ ​​=​​ ​​10
 >>>​​ ​​number​​ ​​*=​​ ​​number
 >>>​​ ​​number
 100

The code above is equivalent to the code below:

 >>>​​ ​​number​​ ​​=​​ ​​10
 >>>​​ ​​number​​ ​​=​​ ​​number​​ ​​*​​ ​​number
 >>>​​ ​​number
 100

The following table contains a summary of the augmented operators you’ve seen plus a few more based on arithmetic operators you learned about in .

Symbol

Example

Result

+=

 x = 7
 x += 2

x refers to 9

-=

 x = 7
 x -= 2

x refers to 5

*=

 x = 7
 x *= 2

x refers to 14

/=

 x = 7
 x /= 2

x refers to 3.5

//=

 x = 7
 x //= 2

x refers to 3

%=

 x = 7
 x %= 2

x refers to 1

**=

 x = 7
 x **= 2

x refers to 49

Where Are the ++ and -- Operators?

After learning about augmented assignment like x += 1, you might expect Python to support x++ (increment) or x-- (decrement) operators like other languages do. But surprisingly, it doesn’t!

Why not? Python avoids these increment and decrement shortcuts to keep the language explicit and readable: “In Python, readability matters more than shorthand.” Instead, you should always write x += 1 or x -= 1, which makes it evident that you’re updating a variable.

Назад: What Is a Type?
Дальше: How Python Tells You Something Went Wro ng