## Python语言中的变量

对于想学习编程的新手来说，有两个问题可能是他们很想知道的，其一是“什么是（计算机）程序”，其二是“写（计算机）程序能做什么”。先说说我对这两个问题的理解：**程序是数据和指令的有序集合**，**写程序就是用数据和指令控制计算机做我们想让它做的事情**。今时今日，为什么有那么多人选择用 Python 语言来写程序，因为 Python 语言足够简单和强大。相较于 C、C++、Java 这样的编程语言，Python 对初学者和非专业人士更加友好，很多问题在 Python 语言中都能找到简单优雅的解决方案。接下来，我们就从最基础的语言元素开始，带大家认识和使用 Python 语言。

### 一些常识

在开始系统的学习 Python 编程之前，我们先来科普一些计算机的基础知识。计算机的硬件系统通常由五大部件构成，包括：**运算器**、**控制器**、**存储器**、**输入设备**和**输出设备**。其中，运算器和控制器放在一起就是我们常说的**中央处理器**（CPU），它的功能是执行各种运算和控制指令。刚才我们提到过，程序是指令的集合，写程序就是将一系列的指令按照某种方式组织到一起，然后通过这些指令去控制计算机做我们想让它做的事情。存储器可以分为**内部存储器**和**外部存储器**，前者就是我们常说的内存，它是中央处理器可以直接寻址的存储空间，程序在执行的过程中，对应的数据和指令需要加载到内存中。输入设备和输出设备经常被统称为 I/O 设备，键盘、鼠标、麦克风、摄像头是典型的输入设备，而显示器、打印机、扬声器等则是典型的输出设备。目前，我们使用的计算机基本大多是遵循“冯·诺依曼体系结构”的计算机，这种计算机有两个关键点：一是**将存储器与中央处理器分开**；二是**将数据以二进制方式编码**。

二进制是一种“逢二进一”的计数法，跟人类使用的“逢十进一”的计数法本质是一样的。人类因为有十根手指，所以使用了十进制计数法，在计数时十根手指用完之后，就只能用进位的方式来表示更大的数值。当然凡事都有例外，玛雅人可能是因为长年光着脚的原因，把脚趾头也都用上了，于是他们使用了二十进制的计数法。基于这样的计数方式，玛雅人使用的历法跟我们平常使用的历法就产生了差异。按照玛雅人的历法，2012 年是上一个所谓的“太阳纪”的最后一年，而 2013 年则是新的“太阳纪”的开始。后来这件事情还被以讹传讹的方式误传为“2012 年是玛雅人预言的世界末日”的荒诞说法。今天有很多人猜测，玛雅文明之所以发展缓慢跟使用了二十进制是有关系的。对于计算机来说，二进制在物理器件上最容易实现的，因为可以用高电压表示 1，用低电压表示 0。不是所有写程序的人都需要熟悉二进制，熟悉十进制与二进制、八进制、十六进制的转换，大多数时候我们即便不了解这些知识也能写程序。但是，我们必须知道，计算机是使用二进制计数的，不管什么样的数据，到了计算机内存中都是以二进制形态存在的。

> **说明**：关于二进制计数法以及它与其他进制如何相互转换，大家可以翻翻名为《计算机导论》或《计算机文化》的书，都能找到相应的知识，此处就不再进行赘述了，不清楚的读者可以自行研究。

### 变量和类型

要想在计算机的内存中保存数据，首先得说一说变量这个概念。在编程语言中，**变量是数据的载体**，简单的说就是一块用来保存数据的内存空间，**变量的值可以被读取和修改**，这是所有运算和控制的基础。计算机能处理的数据有很多种类型，最常见的就是数值，除了数值之外还有文本、图像、音频、视频等各种各样的数据类型。虽然数据在计算机中都是以二进制形态存在的，但是我们可以用不同类型的变量来表示数据类型的差异。Python 语言中预设了多种数据类型，也允许我们自定义新的数据类型，这一点在后面会讲到。我们首先来了解几种 Python 中最为常用的数据类型。

1. 整型（`int`）：Python 中可以处理任意大小的整数，而且支持二进制（如`0b100`，换算成十进制是4）、八进制（如`0o100`，换算成十进制是64）、十进制（`100`）和十六进制（`0x100`，换算成十进制是256）的表示法。运行下面的代码，看看会输出什么。

    ```python
    print(0b100)  # 二进制整数
    print(0o100)  # 八进制整数
    print(100)    # 十进制整数
    print(0x100)  # 十六进制整数
    ```

2. 浮点型（`float`）：浮点数也就是小数，之所以称为浮点数，是因为按照科学记数法表示时，一个浮点数的小数点位置是可变的，浮点数除了数学写法（如`123.456`）之外还支持科学计数法（如`1.23456e2`，表示$\small{1.23456 \times 10^{2}}$）。运行下面的代码，看看会输出什么。

    ```python
    print(123.456)    # 数学写法
    print(1.23456e2)  # 科学计数法
    ```

3. 字符串型（`str`）：字符串是以单引号或双引号包裹起来的任意文本，比如`'hello'`和`"hello"`。

4. 布尔型（`bool`）：布尔型只有`True`、`False`两种值，要么是`True`，要么是`False`，可以用来表示现实世界中的“是”和“否”，命题的“真”和“假”，状况的“好”与“坏”，水平的“高”与“低”等等。如果一个变量的值只有两种状态，我们就可以使用布尔型。

### 变量命名

对于每个变量，我们都需要给它取一个名字，就如同我们每个人都有自己的名字一样。在 Python 中，变量命名需要遵循以下的规则和惯例。

- 规则部分：
  - 规则1：变量名由**字母**、**数字**和**下划线**构成，数字不能开头。需要说明的是，这里说的字母指的是 Unicode 字符，Unicode 称为万国码，囊括了世界上大部分的文字系统，这也就意味着中文、日文、希腊字母等都可以作为变量名中的字符，但是一些特殊字符（如：`！`、`@`、`#`等）是不能出现在变量名中的。我们强烈建议大家把这里说的字母理解为**尽可能只使用英文字母**。
  - 规则2：Python 是**大小写敏感**的编程语言，简单的说就是大写的`A`和小写的`a`是两个不同的变量，这一条其实并不算规则，而是需要大家注意的地方。
  - 规则3：变量名**不要跟 Python 的关键字重名**，**尽可能避开 Python 的保留字**。这里的关键字是指在 Python 程序中有特殊含义的单词（如：`is`、`if`、`else`、`for`、`while`、`True`、`False`等），保留字主要指 Python 语言内置函数、内置模块等的名字（如：`int`、`print`、`input`、`str`、`math`、`os`等）。
- 惯例部分：
  - 惯例1：变量名通常使用**小写英文字母**，**多个单词用下划线进行连接**。
  - 惯例2：受保护的变量用单个下划线开头。
  - 惯例3：私有的变量用两个下划线开头。

惯例2和惯例3大家暂时不用管，讲到后面自然会明白的。当然，作为一个专业的程序员，给变量命名时做到**见名知意**也是非常重要，这彰显了一个程序员的专业气质，很多开发岗位的面试也非常看重这一点。

### 变量的使用

下面通过例子来说明变量的类型和变量的使用。

```python
"""
使用变量保存数据并进行加减乘除运算

Version: 1.0
Author: 骆昊
"""
a = 45        # 定义变量a，赋值45
b = 12        # 定义变量b，赋值12
print(a, b)   # 45 12
print(a + b)  # 57
print(a - b)  # 33
print(a * b)  # 540
print(a / b)  # 3.75
```

在 Python 中可以使用`type`函数对变量的类型进行检查。程序设计中函数的概念跟数学上函数的概念非常类似，数学上的函数相信大家并不陌生，它包括了函数名、自变量和因变量。如果暂时不理解函数这个概念也不要紧，我们会在后续的内容中专门讲解函数的定义和使用。

```python
"""
使用type函数检查变量的类型

Version: 1.0
Author: 骆昊
"""
a = 100
b = 123.45
c = 'hello, world'
d = True
print(type(a))  # <class 'int'>
print(type(b))  # <class 'float'>
print(type(c))  # <class 'str'>
print(type(d))  # <class 'bool'>
```

可以通过 Python 内置的函数来改变变量的类型，下面是一些常用的和变量类型相关的函数。

- `int()`：将一个数值或字符串转换成整数，可以指定进制。
- `float()`：将一个字符串（在可能的情况下）转换成浮点数。
- `str()`：将指定的对象转换成字符串形式，可以指定编码方式。
- `chr()`：将整数（字符编码）转换成对应的（一个字符的）字符串。
- `ord()`：将（一个字符的）字符串转换成对应的整数（字符编码）。

下面的例子为大家演示了 Python 中类型转换的操作。

```python
"""
变量的类型转换操作

Version: 1.0
Author: 骆昊
"""
a = 100
b = 123.45
c = '123'
d = '100'
e = '123.45'
f = 'hello, world'
g = True
print(float(a))         # int类型的100转成float，输出100.0
print(int(b))           # float类型的123.45转成int，输出123
print(int(c))           # str类型的'123'转成int，输出123
print(int(c, base=16))  # str类型的'123'按十六进制转成int，输出291
print(int(d, base=2))   # str类型的'100'按二进制转成int，输出4
print(float(e))         # str类型的'123.45'转成float，输出123.45
print(bool(f))          # str类型的'hello, world'转成bool，输出True
print(int(g))           # bool类型的True转成int，输出1
print(chr(a))           # int类型的100转成str，输出'd'
print(ord('d'))         # str类型的'd'转成int，输出100
```

> **说明**：`str`类型转`int`类型时可以通过`base`参数来指定进制，可以将字符串视为对应进制的整数进行转换。`str`类型转成`bool`类型时，只要字符串有内容，不是`''`或`""`，对应的布尔值都是`True`。`bool`类型转`int`类型时，`True`会变成`1`，`False`会变成`0`。在 ASCII 字符集和 Unicode 字符集中， 字符`'d'`对应的编码都是`100`。

### 总结

在 Python 程序中，我们可以**使用变量来保存数据**，**变量有不同的类型**，常用的类型有`int`、`float`、`str`和`bool`。在有需要的情况下，可以通过 Python 内置的函数对变量进行类型转换。变量是可以做运算的，这是解决很多问题的先决条件，我们会在下一课中为大家详细介绍变量的运算。

