devStandard/docs/learning/9-python/1-python基础语法.md
2025-03-29 14:35:49 +08:00

1146 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Python基础语法
第一个程序
```python
print("hello word")
```
## 数据类型
* 数字 Number
* 整数 int
* 浮点数 float
* 复数 complex 4+3j
* 布尔 bool
* 字符串 String : 用单引号或者双引号包裹, 或者三对双引号 `"""字符串"""`
* 列表 List : 有序的可变序列
* 元组 Tuple : 有序的不可变序列
* 集合 Set : 无序不重复集合
* 字典 Dictionary : 无序key-value集合
`type(1)` : 检查类型
## 注释
```python
# 单行注释
'''
三个单引号多行注释
'''
"""
或者三个双引号
"""
```
## 风格
### 代码块
===不使用{}, 而是缩进表示代码块. 同一个代码块缩进的空格数必须一致===
```python
if True:
print("true")
else:
print("false")
```
### 多行语句
```python
# 用 \ 实现换行
total = one + two + \
three + four
# 在 [] {} 中不需要 \
total = [one , two
three, four]
```
### 保留字
```python
import keyword
print(keyword.kwlist)
'''
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
'''
```
## 变量
```python
# 语法:
变量名 = 变量值
```
## 数据类型转换
```python
int(x)
float(x)
str(x)
```
## 标识符
* 内容限定: 英文 数字 下划线, ===数字不能在空头===
* 大小写敏感
* 不可使用关键字, 关键字也是大小写敏感
变量命名规范: 蛇形命名法: ===全小写, 下划线===
## 运算符
* 算数运算符
* * * * /
* // 取整除 : 9//2输出4
* % 取余
* ** 指数
* 赋值运算符
* =
* `+= -= *= /= //= %= **=` 复合赋值运算符
===没有 ++ -- ===
## 字符扩展
* `\` 转义
* 拼接: 加号, 只能用字符串拼字符串
* 占位格式化
```python
"""
语法:
%s在字面量中占位, 后面 % 变量
顺序不能变
%s 字符串
%d 整数
%f 浮点数
"""
name = "张三"
age = 18
message1 = "%s是男性" % name
message2 = "%s今年%d岁了" % (name, age)
print(message1,message2)
```
* 格式化的精度控制
```python
"""
m.n m表示宽度, n表示小数的精度
# 示例
%5d # 宽度控制为5, 少的宽度用空格补全; 如果宽度小于实际, 不生效; 宽度包含小数和小数点
%5.2f # 宽度为5, 两位小数, 小数部分4舍5入
%.2f # 不限制宽度, 只限制小数
"""
num = 11.456
print("%7d" % num) # 11
print("%7.2f" % num) # 11.46
print("%.2f" % num) # 11.46
```
* 快速格式化
```python
# f"内容{变量}"
# 没有类型和精度控制
# f format
name = "张三"
age = 18.5
message = f"{name}今年{age}岁了"
print(message)
```
* 格式化中使用表达式
```python
print("11的类型是%s" % type(11))
print(f"11的类型是{type(11)}")
```
## 数据输入
```python
"""
input() 接收键盘输入
input("提示文本")
获取的是字符串格式,其他格式需要自行转换
"""
name = input("请输出你的名字")
print(f"name: {name}")
```
## 判断语句
* 比较运算符:
```python
>
<
==
!==
>=
<=
```
* 布尔类型: `True` `False` ===大写===
* if 语句
```python
if 条件:
执行语句
```
* if else 语句
```python
if 条件:
执行语句
else:
执行语句
```
* if elif else
```python
if 条件:
执行语句
elif 条件:
执行语句
else:
执行语句
```
* 嵌套
```python
# 关键 缩进
if 条件:
执行语句
if 条件:
执行语句
```
## while 循环
```python
while 条件:
执行语句
```
* 嵌套
```python
while 条件:
执行语句
while 条件:
执行语句
```
## for in 循环
```python
for 临时变量 in 序列类型
执行的代码
```
```python
str="hello word"
for i in str:
print(i)
```
* 嵌套
```python
for 临时变量 in 序列类型
执行的代码
for 临时变量 in 序列类型
执行的代码
```
## range 语句
> 生成数字序列
```python
# 生成一个从0开始到num的数字序列, 不包含num本身
range(num)
range(5)
# [0, 1, 2, 3, 4]
# 从 num1 到num2, 不包含num2
range(num1, num2)
# 从num1到num2, 步进为step
range(num1, num2, step)
range(2, 7, 2)
# 2, 4, 6
```
使用场景:
```python
for x in range(10):
print(x)
```
## print 控制是否换行
> print("", end=""), end参数控制输出的结尾内容, 而不是默认换行
99乘法表
```python
for i in range(1,10):
for j in range(1,i+1):
print(f"{i}*{j}={i*j} \t",end="")
print()
```
## continue 和 break
continue 临时跳过
break 结束
示例:
```python
for x in range(1, 6):
if x == 3:
continue
print(x)
```
```python
for x in range(1, 6):
if x == 3:
break
print(x)
```
## 函数
```python
def 函数名(形参):
函数体
return 返回值
# 调用
函数名(实参)
```
函数注释
```python
def 函数名(x, y):
"""
函数说明
:param x: 行参x的说明
:param y: 行参y的说明
:return: 返回值的说明
"""
函数体
return 返回值
```
示例:
```python
def add(num1, num2):
"""
这是一个计算两个数相加的函数
:param num1: 第一个数
:param num2: 第二个数
:return: 两个数相加的结果
"""
return num1 + num2
print(add(1,2))
```
## 列表
```python
变量名 = []
变量名 = list()
变量名 = [元素1, 元素2, ...]
```
### 下标索引
```python
# 从0开始
变量名[下标]
# 反向索引
# 从-1开始
变量名[-1]
# 嵌套列表
变量名[0][0]
```
### 常用方法
* 增:
* 插入: `列表.insert(下标, 值)`
* 追加: `列表.append(值)`
* 把列表内容取出追加到列表: `列表1.extend(列表2)`
* 删:
* `del 列表[下标]`
* `被取出的元素=列表.pop(下标)`
* `列表.remove(元素)`:从前到后第一个匹配项
* `列表.clear()`: 清空
* 改: `列表[下标]=新的值`
* 查: 查询下标 `列表.index(元素)`
* 统计元素个数: `列表.count(元素)`
* 长度: `len(列表)`
### 列表的遍历
* while
```python
list = ["a", "b", "c"]
index = 0
while index < len(list):
print(len[i])
index+=1
```
* for in
```python
list = ["a", "b", "c"]
for x in list:
print(x)
```
## 元组
> 只读的列表, 定义完成, 不能修改
```python
元组 = (元素1, 元素2, ...)
元组 = tuple()
```
===只有一个元素的元组, 必须带逗号===
```python
元组 = (元素1, )
```
### 下标索引
```python
t1 = ((1, 2, 3), (4, 5, 6))
element = t1[1][2]
print(element)
```
### 方法
* 查: `元组.index(元素)`
* 统计:
* 元素的数量 `元组.count(元素)`
* 长度: `len(元组)`
### 遍历
while
for in
### 修改
```python
t2 = ((1, 2, 3), [4, 5, 6])
t2[1][2] = 7 # 元组里的数组里的元素可以修改
print(t2)
```
## 字符串
```python
str = "hello word"
print(str[0])
print(str[-1])
```
===字符串是不可修改的数据容器===
### 常用的方法
* `字符串.index(字符)`
* 替换: 不是修改, 是得到新的字符串 `newstr = 字符串.replace(字符1, 字符2)`
* 分割: `列表 = 字符串.split(用来分割的字符)`
* 去首尾空格: `newstr = 字符串.strip()`
* 去指定字符: `newstr = 字符串.strip(要去除的字符)`
* ===去除是逐个去除=== `print("12hello word21".strip("12"))`, 结果是 hello word, 不止12被去除了,21也被去除了
* 统计次数: `count = 字符串.count(字符)`
* 长度: `num = len(字符串)`
## 序列的切片
> 列表 元组 字符串 都支持切片
> 对序列切割不影响序列本身, 而是返回新的序列
```python
序列[起始:结束:步长]
# 起始为空, 表示从头开始
# 结束为空, 表示到尾. 不为空, 到该下标结束, 不包含该下标所在的元素
# 默认为1,可省略, 表示连续取为n, 表示跳过n-1个; 为正, 表示从左到右; 为负, 表示反方向(下标也得反方向).
```
示例:
```python
print([1, 2, 3, 4, 5, 6, 7, 8, 9][1:7])
# 输出[2, 3, 4, 5, 6, 7]
print([1, 2, 3, 4, 5, 6, 7, 8, 9][1:7:2])
# 输出[2, 4, 6]
print([1, 2, 3, 4, 5, 6, 7, 8, 9][1:7:3])
# 输出[2, 5]
print("1234567"[::-1])
# 7654321
```
## 集合
```python
# 集合不支持重复, 自带去重
new_set = {元素1, 元素2, ...}
new_set2 = set()
```
===不支持下标索引访问===
### 常用的方法
```python
# 增
集合.add(元素)
# 删
集合.remove(元素)
# 随机取出一个元素, 同时集合被修改, 该元素被移除
集合.pop()
# 清空
集合.clear()
# 差集, 集合1 集合2不变, 得到集合1有集合2没有的
新集合 = 集合1.difference(集合2)
print({1, 2, 3}.difference({3, 4, 5}))
# 输出 {1, 2}
# 消除差集, 集合1被修改, 集合2不变, 在集合1内删除和集合2相同的内容
集合1.difference_upate(集合2)
my_set={1, 2, 3}
my_set.difference_update({3, 4, 5})
print(my_set)
# 集合合并, 集合1 集合2不变, 返回合并后的集合
集合1.union(集合2)
print({1, 2, 3}.union({3, 4, 5}))
# 长度
len(集合)
```
### 遍历
没有下标, 不支持 while, 但可以用for in
## 字典
```python
{key1: value1, key2: value2, ...}
emy_dict = {} # 不是集合
# 或者
emy_dict = dict()
# 取出值
字典[key]
===key不能是字典===
```
### 常用方法
#### 新增/更改
```python
# 不存在就是新增, 已存在就是更改
字典[key] = value
```
#### 删
```python
# 取出来的同时, 也从原字典中删除
value = 字典.pop(key)
```
#### 清空
```python
字典.clear()
```
#### 获取所有的键
```python
keys = 字典.keys()
```
#### 长度
```python
len(字典)
```
### 遍历
方法一:
```python
dict = {"name": "张三", "age": 18, "address": "北京"}
for key in dict.keys():
print(dict[key])
```
方法二:
```python
dict = {"name": "张三", "age": 18, "address": "北京"}
for key in dict:
print(dict[key])
```
## 数据容器的通用操作
1. 遍历
2. `len(容器)`
3. `max(容器)` 最大元素
4. `min(容器)` 最小元素
5. 容器转换
1. `list(容器)` 字典转列表, 会只保留key
2. `str(容器)`
3. `tuple(容器)`
4. `set(容器)`
6. 通用排序: `sorted(容器, [reverse=True])` 把内容排序后放到列表中
## 字符串比较大小
数字 字符 是如何比较大小的: 按照ASCII的码值
比较的时候是一位位从左到右比较的, 只要有一位大, 就整体大
## 函数
### 返回多个值
```python
# 用逗号隔开
def test():
return 1, 2
a, b = test()
print(a, b)
```
### 关键字传参
```python
# 位置传参
def sum(num1, num2):
return num1 + num2
sum(1, 2)
# 关键字传参
# 键=值
# 顺序可以打乱
sum(num2=1, num1=2)
# 还可以混用, 但位置传参在前, 关键字传参在后
```
### 缺省/默认参数
===默认参数必须写到最后面===
```python
def user_info(name, age, gender="男"):
print(name, age, gender)
```
### 可变参数
```python
# 位置传递
# 一个星号
# 传递的所有参数都会被args收集, 合并成一个元组
def user_info(*args):
print(args)
user_info("张三", 18,"男")
# ('张三', 18, '男')
# 关键字传递
# 两个星号
# 参数必须是键值对的形式
# 字典
def user_info(**kwargs):
print(kwargs)
user_info(name="张三", age=18, gender="男")
# {'name': '张三', 'age': 18, 'gender': '男'}
```
### lambda 匿名函数
```python
# 函数体只能写一行
lambda 参数: 函数体
def test(fn):
res = fn(1, 2)
print(res)
test(lambda x, y: x + y)
```
## 文件操作
### 文件编码
* UTF-8
* GBK
* Big5
### 文件的打开
```python
open(name, mode, encoding)
# name 文件名或路径
# mode r只读 w写入 a追加
# encoding 编码格式, 常用UTF-8
f = open("test.txt", "r", encoding="utf-8")
print(type(f))
# <class '_io.TextIOWrapper'>
```
### 读取
* `read([num])`: 不传参时读取所有;传参时, 读取 num 字节
* `readlines()`: 读取全部行, 依次存到列表中
* `readline()`: 一次读取一行
注意: 如果多次调用 read() 方法, 会记录上次读取的位置, 例如:
```python
f = open("test.txt", "r", encoding="utf-8")
print(f.read(2))
print(f.read())
# 从第三个字节开始读取
print(f.readlines())
# 为空
```
* for in 循环读取文件
```python
for line in open("test.txt", "r", encoding="utf-8"):
print(line)
```
### 关闭
```python
# 结束对文件的占用
f = open("test.txt", "r", encoding="utf-8")
f.close()
```
`with open() as f` 语法会自动关闭
示例:
```python
with open("test.txt", "r") as f:
f.readlines()
```
### 写入
```python
f.write("写入的内容")
# 内容刷新, 从内存写入到硬盘
# 好处是避免频繁操作硬盘
f.flush()
```
示例:
```python
# w 模式
# 当文件不存在时, 创建该文件
# 当文件存在, 会清空
f = open("test.txt", "w")
f.write("hello word\n")
f.write("123")
f.flush()
f.close()
# close()方法内置了 flush(), 关闭时也会自动写入硬盘
```
### 追加
```python
# a 模式
f = open("test.txt", "a")
```
## 异常的捕获
```python
try:
可能发生错误的代码
except:
如果出现错误执行的代码
```
示例:
```python
try:
f = open("none.txt","r")
except:
print("文件不存在")
```
### 捕获指定的异常
```python
try:
可能发生错误的代码
except 异常的类型 as e:
如果异常类型符合就执行
e是异常信息
```
示例:
```python
try:
print(name)
except NameError as e:
print(e)
```
### 捕获多个异常
```python
# 用元组来指定异常类型
try:
可能发生错误的代码
except (类型1, 类型2, ...) as e:
如果异常类型符合就执行
e是异常信息
```
示例:
```python
try:
print(1/0)
except (NameError,ZeroDivisionError) as e:
print(e)
```
### 捕获所有异常
```python
# except 不指定类型就可以捕获所有异常
# 也可以指定类型 Exception
try:
可能发生错误的代码
except Exception as e:
如果异常类型符合就执行
e是异常信息
```
示例:
```python
try:
print(name)
except Exception as e:
print(e)
```
### 主动抛出异常
```python
raise Exception("异常消息")
```
### else
```python
try:
可能发生错误的代码
except Exception as e:
如果异常类型符合就执行
e是异常信息
else:
没有异常时执行的代码
```
### finally
```python
try:
可能发生错误的代码
except Exception as e:
如果异常类型符合就执行
e是异常信息
else:
没有异常时执行
finally:
无论如何都要执行
```
### 异常的传递
```python
# 异常会一层层往外传
# 只要函数具有调用关系, 只须在最顶级捕获异常
def fun1():
print(name)
def fun2():
fun1()
def main():
try:
fun2()
except Exception as e:
print(e)
main()
```
## 模块
### 导入
```python
[from 模块名] import [模块||变量|函数|*] [as 别名]
import 模块名
模块名.函数()
import 模块名1, 模块名2
```
示例:
```python
import time
print(time.time())
time.sleep(5)
print(time.time())
```
```python
from time import sleep
print(time.time())
sleep(5)
print(time.time())
```
```python
# 也是导入全部
from time import *
sleep(5)
```
```python
# as 别名
from time import sleep as t
t(5)
```
### 自定义模块
```python
# 新建一个py文件
# 在该文件里写函数
# import 文件名
# 或者
# from 文件名 import 函数
```
* 模块导入的时候会执行模块里的语句
例如:
```python
# module.py
def sum(a,b):
print(a+b)
sum(1,2)
# test.py
import module
# 这里导入时就会输出3
```
改造:
```python
def sum(a,b):
print(a+b)
if __name__ == "__main__":
sum(1,2)
# 直接运行该文件时, 内置变量 __name__ 就会设置为 __main__
# 作为模块被导入时, if 里的代码不执行
```
* `__all__` 变量
```python
__all__=["sum"]
def sum(a,b):
print(a+b)
def sub(a, b):
print(a-b)
```
```python
from module import *
# 通过*只能导入 __all__ 列出的函数
# __all__ 不定义, 就可以导入全部
```
## 包
> 文件夹里有多个模块
```
1. 创建文件夹
2. 创建 __init__.py 文件
3. 创建 模块.py
4. 使用: import 包名.模块名
包名.模块名.函数
或者
from 包名 import 模块名
模块名.函数()
或者
from 包名.模块名 import 函数
函数()
结构:
文件夹名为包名
__init__py
module1.py
module2.py
```
示例:
```python
import my_package.module1
import my_package.module2
my_package.module1.sum(1, 2)
my_package.module2.sub(1, 2)
```
或者
```python
from my_package import module1
from my_package import module2
module1.sum(1, 2)
module2.sub(1, 2)
```
```python
from my_package.module1 import sum
from my_package.module2 import sub
sum(1, 2)
sub(1, 2)
```
* `__all__`
```python
# 写在__init__.py
__all__ = ["module1", "module2"]
```
## 安装第三方包
```python
pip install 包名
```