Hands on Python
Background
Python 作为一个高级编程语言 (high-level language),它的主要工作是将用户编写的 Python 源代码解释成机器能理解的成字节码 (bytecode),以便让机器执行指令。
相比于机器语言和汇编语言等低级语言 (low-level language),使用高级编程语言编写代码有一些好处:代码更少也更易读,编写代码所需的时间更短;更容易做到跨平台运行。
Python 很重要的一个组件是 Python Interpreter。解释器的主要工作是解释并运行 Python: 读取用户编写的 Python 源代码;对源代码进行词法分析,将代码分解成词法单元(tokens);之后进行语法分析,构建抽象语法树(Abstract Syntax Tree,AST)来表示代码的结构;接着将抽象语法树编译成 bytecode,这是一种中间形式的代码;最后,Python 解释器会逐行执行字节码指令,将其转换为机器码并执行,实现源代码的功能。
执行 Python 有两种模式:immediate mode & script mode. 前者是在 terminal 界面进入 Python 解释器的窗口进行即时交互;第二种是通过编写扩展名为 py 的 Python 脚本,使用 Python 解释器去执行该脚本。
在日常调试和数据分析过程中,另一个常用的 python 交互方式是 Jupiter Notebook。
Installation
根据操作系统不同,安装 Python 的方式有很多,详情可以参考 Downlaod Python。笔者推荐使用 Anaconda 作为 Python 的环境管理工具。
检验 Python 环境配置是否已经完成:
python --version
Data Type
Python 中常见的数据类型包括:
- 整数(int):表示整数值,如 5、-3;
- 浮点数(float):表示带有小数点的数值,如 3.14、-0.001;
- 字符串(str):表示文本数据,如 ‘hello’、”world”;
- 布尔值(bool):表示逻辑值,只有两个取值:True 和 False;
- 列表(list):有序、可变的集合,如 [1, 2, 3];
- 元组(tuple):有序、不可变的集合,如 (1, 2, 3);
- 集合(set):无序、不重复的集合,如 {1, 2, 3};
- 字典(dict):无序的键值对集合,如 {‘name’: ‘Alice’, ‘age’: 30}。
Script Structure
在生产级别的 Python 编程中,一个 Python 脚本通常由以下部分构成:
1. 导入模块
在开头导入代码所需的模块,以扩展 Python 的功能和复用代码。例如:
import os
import sys
from datetime import datetime
注:你可以在 Python 标准库, PyPI (Python Package Index), Awesome Python 找到丰富的 Python 库及其功能详情;也可以使用 help(function_name)
可以查看已导入方法内置的说明。
2. 全局变量和常量定义
定义全局变量和常量,用于在整个脚本中共享数据。例如:
MAX_RETRIES = 3
DEBUG_MODE = True
3. 函数和类定义
编写函数和类来组织代码逻辑和实现功能。函数用于封装可重复使用的代码块,类用于组织相关属性和方法。例如:
def calculate_area(radius):
return 3.14 * radius ** 2
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
注:其中 __init__
是 Python 中的构造函数,用于在创建对象时初始化对象的属性。
4. 主程序逻辑
编写主要的程序逻辑,包括流程控制、数据处理、调用函数等。这部分代码通常位于脚本的最顶层,用于实现脚本的主要功能。例如:
if __name__ == "__main__":
radius = 5
area = calculate_area(radius)
print(f"The area of the circle is: {area}")
注:if __name__ == "__main__"
被用来判断当前脚本是否作为主程序运行,加上这段代码可以防止在被其他脚本导入时执行了不必要的代码;当 Python 解释器运行一个脚本时,__name__
变量会被设置为 "__main__"
,而如果该脚本被作为模块导入到其他脚本时,__name__
变量会被设置为模块的名称。
5. 异常处理
添加适当的异常处理机制,以处理可能出现的错误和异常情况,确保程序的稳定性和可靠性。例如:
try:
result = 10 / 0
except ZeroDivisionError as e:
print("Error: Division by zero!")
注:可以通过 Python 异常文档 查看完整的 Exception 列表,也可以通过 help(ExceptionNameError)
查看特定异常的详细信息。
6. 日志记录
使用日志记录模块记录程序运行时的信息、警告和错误,以便进行故障排查和监控。例如:
import logging
logging.basicConfig(filename='app.log', level=logging.INFO)
logging.info('Program started')
Useful Libraries
1. pdb —— The Python Debugger
pdb 是一个 python 中用于调试代码的模块,它的用法有两种,在代码行中插入:
import pdb; pdb.set_trace()
或者使用 python3.7 之后内置的 breakpoint()
Example: Debug Guessing Number
random.randint(a, b) 返回一个 a <= N <= b 的随机整型,用 Python 执行下面的脚本得不到我们想要的结果。使用 breakpoint() 来寻找原因。
# import pdb
from random import randint
# pdb.set_trace()
breakpoint()
answer = randint(0, 1)
n = input("Guess: 0 or 1?")
if n == answer:
breakpoint()
print("Correct!")
else:
breakpoint()
print(f"Incorrect. The answer was {answer}.")
-> answer = randint(0, 1)
(Pdb) n
-> n = input("Guess: 0 or 1?")
(Pdb) !answer
1
(Pdb) n
Guess: 0 or 1?1
-> if n == answer:
(Pdb) continue
-> print(f"Incorrect. The answer was {answer}.")
(Pdb) !(n == answer)
False
(Pdb) !type(n)
<class 'str'>
(Pdb) !type(answer)
<class 'int'>
(Pdb) continue
Incorrect. The answer was 1.
通过 debug 发现,比较时变量 n 和变量 answer 类型不同,将第 7 行代码按如下调整即可修复功能:
n = int(input("Guess: 0 or 1?"))
在 debug 模式下,键入 help
查看可以使用的所有命令,以下是开发中最常用的命令及其说明:
| pdb Command | Action |
| n or next | Run the next line of code |
| s or step | Step into current line(usually a function call) |
| r or return | Return from the current function |
| l or list | List the surrounding code lines |
| interact | Starts an interactive Python interpreter |
| c or continue | Continue running (until next breakpoint or exit) |
| b or break | Set a breakpoint for a specific line or function |
| ! | Special prefix to say "run this as Python code" |
| pp | Pretty-print the value of a Python expression |
To be continued…