语法基础
本文介绍 Python 的语法基础,即不 import 任何包的情况下需要涉及到的内容,标准文档见 Reference - Python Docs 官网。
数据类型¶
Python 是动态类型语言,变量不需要声明类型,赋值时会自动确定类型。
Tip
Python 支持在声明变量时写上预期的数据类型,但并不会主动检查数据类型不匹配的错误,可以借助第三方 类型检查 工具来避免此类错误。
整型¶
浮点型¶
布尔型¶
字符串¶
基本用法:
字符转义:
其中:
- Python 会对其中的特殊字符转义,例如
\t会被转义为一个 tab; r表示输出原始内容,不会对其中的内容进行转义。
字符模板 (f-string):
其中:
- 跨行字符串可以使用小括号包裹;
- 模板中
:.1f表示给浮点数四舍五入保留 1 位小数。
列表¶
可变序列。可以理解为线性表,\(O(1)\) 尾插入、\(O(1)\) 尾删除:
# 初始化
fruits = ["apple", "banana", "cherry"]
# 尾插入
fruits.append("orange")
# 尾删除
fruits.pop()
# 删除第一个匹配到的元素
fruits.remove("banana")
print(fruits[0]) # 访问列表第一个元素
print(fruits[1:3]) # 切片,访问第二到第三个元素
列表推导式是创建列表的一种简洁方式:
元组¶
不可变的序列类型,一旦创建不能修改:
字典¶
由键值对组成:
person = {"name": "Alice", "age": 25}
person["age"] = 26 # 修改字典中的值
person["city"] = "New York" # 添加新的键值对
print(person["name"]) # 访问值
集合¶
一个无序且不重复的元素集合:
colors = {"red", "green", "blue"}
colors.add("yellow") # 添加元素
colors.remove("green") # 删除元素
print(colors)
运算符¶
Python 有以下 运算符:
Python 的 运算符优先级(越往下等级越低):
| 运算符 | 描述 |
|---|---|
(expressions...) |
绑定或加圆括号的表达式 |
[expressions...] |
列表显示 |
{key: value...} |
字典显示 |
{expressions...} |
集合显示 |
x[index] |
抽取 |
x[index:index] |
切片 |
x(arguments...) |
调用 |
x.attribute |
属性引用 |
await x |
await 表达式 |
** |
乘方 |
+x, -x, ~x |
正,负,按位非 NOT |
*, @, /, //, % |
乘,矩阵乘,除,整除,取余 |
+, - |
加和减 |
<<, >> |
移位 |
& |
按位与 AND |
^ |
按位异或 XOR |
| |
按位或 OR |
in, not in, is, is not, <, <=, >, >=, !=, == |
比较运算,包括成员检测和标识号检测 |
not x |
布尔逻辑非 NOT |
and |
布尔逻辑与 AND |
or |
布尔逻辑或 OR |
if -- else |
条件表达式 |
lambda |
lambda 表达式 |
:= |
赋值表达式 |
流程控制¶
条件语句 if、elif、else 用于分支控制。
循环语句 for 和 while 用于重复控制。
# for 循环
for i in range(5): # 输出 0 到 4
print(i)
# while 循环
count = 0
while count < 3:
print("count:", count)
count += 1 # 增加 count 的值
函数¶
Python 使用 def 关键字定义函数。
def greet(name):
return "Hello, " + name
message = greet("Alice")
print(message) # Hello, Alice
解包机制¶
Python 中的解包机制让参数传递变得更灵活。解包分成两类:
- 函数定义处,收集参数。
*args用来接收多余的「位置参数」,而**kwargs用来接收多余的「关键字参数」; - 函数调用处,展开参数。
*用来展开序列(可迭代对象),**用来展开字典。
解包机制的本质,是让 Python 的参数系统脱离固定形态,转而以更抽象的方式处理数据结构,使得语言表达能力在工程层面保持灵活却不混乱。
位置参数的收集与展开:
-
函数定义处,用于接收任意数量的「位置参数」并将它们收集为一个元组:
-
函数调用处,把一个序列展开为多个位置参数:
关键字参数的收集与展开:
-
函数定义处,用于接收任意数量的「关键字参数」并将它们组织为一个字典:
-
函数调用处,把一个字典展开为多个关键字参数:
lambda¶
lambda 函数是一种简洁的匿名函数,通常用于简单的函数体。
类¶
Python 是面向对象的语言,使用 class 关键字定义类。
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
# 强私有方法(前置双下划线)
def __calculate_dog_years(self):
"""将狗的年龄转换为人类年龄"""
return self.age * 7
# 公有方法
def get_human_age(self):
# 在类内部可以正常调用
human_age = self.__calculate_dog_years()
return f"{self.name} is {human_age} years old in human years."
dog = Dog("Buddy", 3)
# 调用公有方法
print(dog.get_human_age()) # Buddy is 21 years old in human years
# 调用私有方法(报错)
print(dog.__calculate_dog_years()) # AttributeError
# 强制调用私有方法(不推荐)
print(dog._Dog__calculate_dog_years()) # 21
模块¶
模块即一个以 .py 为后缀的代码文件,其中可以包括类、函数、变量等任意 Python Object。
__all__¶
模块内的 __all__: list[str] 变量用来约束当前模块暴露出去的对象。有助于明确一个模块中哪些是可以公开调用的,哪些仅仅是内部使用的。
import math
__all__ = ["Demo", "GLOBAL_VAR"]
GLOBAL_VAR = "hello"
class Demo:
def __init__(self):
print(f"cos(1) = {math.cos(1)}")
def fun():
print("this is function")
{
'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001EA08FAC380>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'__file__': 'e:\\python\\demos\\fastapi-demo\\src\\cls_all_main.py',
'__cached__': None,
'Demo': <class 'cls_all.Demo'>,
'GLOBAL_VAR': 'hello'
}
import math
# __all__ = ["Demo", "GLOBAL_VAR"]
GLOBAL_VAR = "hello"
class Demo:
def __init__(self):
print(f"cos(1) = {math.cos(1)}")
def fun():
print("this is function")
{
'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000028A84E6C380>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'__file__': 'e:\\python\\demos\\fastapi-demo\\src\\cls_all_main.py',
'__cached__': None,
'math': <module 'math' (built-in)>,
'GLOBAL_VAR': 'hello',
'Demo': <class 'cls_all.Demo'>,
'fun': <function fun at 0x0000028A84EB0900>
}
异常¶
现实场景下,程序的输入或运行几乎不可能始终正确,为了避免程序在出现异常时直接宕机,程序员需要主动编写代码,来应对可能的异常。基本异常处理逻辑主要分两步:
- 产生异常:Python 使用
raise关键字来产生异常。 - 捕获异常:Python 使用
try、except、finally关键字捕获异常。
在发生 raise ErrorType() 后,Python 会做三件事:
- 构造异常对象;
- 停止当前函数的执行;
- 基于函数调用栈「逐层向上」查找异常处理器(即
try, except逻辑)。
产生异常¶
基本语法:
常见异常:
# 模块没找到
raise ModuleNotFoundError("module not found")
# 文件没找到
raise FileNotFoundError("file not found")
# 除零
raise ZeroDivisionError("division by zero")
捕获异常¶
基本语法:
其基本逻辑是:
try后跟随基本业务逻辑;- 如果出现 A 错误,则执行
handle()函数(针对任意异常); - 如果出现 B 错误,则执行
handle(e)函数(针对 B 异常); - 如果没有出现错误,则执行
else后面的逻辑; - 无论上述结果如何,都会执行
finally后面的逻辑。
迭代器与生成器¶
迭代器是可以遍历的对象,生成器则是使用 yield 来定义的惰性迭代器。