//学习LangChain的时候需要一点有关python的前置知识
目录
[1.0 常量和表达式](#1.0 常量和表达式)
[2.0 变量和类型](#2.0 变量和类型)
[3.0 注释](#3.0 注释)
[4.0 输入和输出](#4.0 输入和输出)
[5.0 运算符](#5.0 运算符)
[6.0 语句](#6.0 语句)
[7.0 函数](#7.0 函数)
[8.0 变量的作用域](#8.0 变量的作用域)
[9.0 函数执行过程](#9.0 函数执行过程)
[10.0 链式调用](#10.0 链式调用)
[11.0 嵌套调用](#11.0 嵌套调用)
[12.0 函数的递归](#12.0 函数的递归)
[13.0 参数默认值](#13.0 参数默认值)
[14.0 关键字参数](#14.0 关键字参数)
[1.0 列表和元组](#1.0 列表和元组)
[2.0 字典](#2.0 字典)
[3.0 文件](#3.0 文件)
[4.0 使用库](#4.0 使用库)
一、认识python
搭建python环境 安装PyCharm就跳过了 //要注意的是升级成企业版会用的更舒服一点

二、Python基础语法
1.0 常量和表达式
形如 1 + 2 - 3 这样是算式, 在编程语言中称为表达式, 算式的运算结果, 称为表达式的返回值
其中 1 , 2 , 3 这种称为 字面值常量, + - * / 这种称为 运算符 或者 操作符
2.0 变量和类型
有的时候, 我们需要进行的计算可能更复杂一些, 需要把一些计算的中间结果保存起来. 这个时候就需要用到 变量.
python
avg = (67.5 + 89.0 + 12.9 + 32.2) / 4
total = (67.5 - avg) ** 2 + (89.0 - avg) ** 2 + (12.9 - avg) ** 2 + (32.2 - avg)
** 2
result = total / 3
print(result)
avg, total, result 均为变量 变量可以视为是一块能够容纳数据的空间. 这个空间往往对应到 "内存" 这样的硬件设备上
定义变量:
a = 10 变量名注意的规则:变量名由数字和字母下划线构成 数字不能开头
使用变量:
python
a = 10
print(a) //读取变量的值
a = 20
print(a) //修改变量的值
变量的类型:
Python变量的类型不需要显示指定 而是在赋值的时候确定的
python
a = 10
print(type(a)) python的int类型的变量,表示的数据范围是没有上限的
只要内存足够大,理论上就可以表示无限大小的数据
a = 0.5
print(type(a)) python的小数只有float一种类型 没有double类型
但是实际上python的float就相当于Java的double 表示双精度浮点数
a = 'hello'
print(type(a)) python中单引号和双引号构成的字符串没有区别
a = 'hello'
print(len(a)) //获取字符串长度
a = 'hello'
b = 'world'
print(a + b) //字符串拼接
......
a = 10
print(type(a))
a = 'hello'
print(type(a)) 动态类型特性 在python中,一个变量是什么类型,是可以在程序运行过程中发生变化的
这个特性称为动态类型
//这是一把双刃剑 对于中小型程序,可以大大解约代码量 比如写一段代码就可以同时支持多种类型
对于大型程序 则提高了模块之间的交互成本 A写的代码难以被B理解
3.0 注释
两种风格的注释:
java
# 这是一行注释. 使用# 开头的都是注释
"""
这是文档字符串
这是文档字符串
""" 使用三引号括起来的成为 文档字符串
也可以视为一种注释
4.0 输入和输出
python
print('hello')
num = 10
print(f'num = {num}') f或者F开头的字符串就是f-string 格式化字符串字面量
在字符串内部,可以使用花括号直接嵌入变量或表达式 python会自动计算它们的值并换成字符串填进去
print(f"两倍 num 是 {num * 2}") # 输出:两倍 num 是 20
python使用input函数 从控制台读取用户的输入
num = 0
num = input('请输入一个整数: ')
print(f'你输入的整数是 {num}')
5.0 运算符
算数运算符 关系运算符
逻辑运算符 :and 并且 有一个假就是假 or或者 一真则是真的 not逻辑取反:略略略你懂的
a<b and b<c 等价于 a<b<c
关于短路求值
和其他编程语言类似, Python 也存在短路求值的规则.
对于 and, 如果左侧表达式为 False, 则整体一定为 False, 右侧表达式不再执行.
对于 or, 如果左侧表达式为 True, 则整体一定为 True, 右侧表达式不再执行.
python
print(10 > 20 and 10 / 0 == 1)
print(10 < 20 or 10 / 0 == 1)
赋值运算符:
python
= 表示赋值
a = b = 10 链式赋值
a, b = 10, 20 多元赋值
交换两个变量:基于多元赋值
a = 10
b = 20
a, b = b, a
复合赋值符
a = 10 a = a + 1 print(a)
其中 a += 1 等价于 a = a + 1 . 其他复合赋值运算符也是同理
6.0 语句
顺序语句:
默认情况下,python的代码执行顺序是按照从上到下的顺序,依次执行的
python
print("1")
print("2")
print("3")
条件语句:
条件语句能够表达 "如果 ... 否则 ..." 这样的语义. 这构成了计算机中基础的 逻辑判定.
条件语句 也叫做 分支语句, 表示了接下来的逻辑可能有几种走向
python
Python 中使用 if else 关键字表示条件语句
(1)if
if expression:
do_something1
do_something2
next_something
如果 expression 值为 True, 则执行 do_something1, do_something2, next_something
如果 expression 值为 False, 则只执行 next_something, 不执行 do_something1, do_something2
(2)if-else
if expression:
do_something1
else:
do_something2
如果 expression 值为 True, 则执行 do_something1
如果 expression 值为 False, 则执行 do_something2
(3)if-elif-else
if expression1:
do_something1
elif expression2:
do_something2
else:
do_something3
如果 expression1 值为 True, 则执行 do_something1
如果 expression1 值为 False, 并且 expression2 为 True 则执行 do_something2
如果 expression1 值为 False, 并且 expression2 为 False 则执行 do_something3
注意:python中的条件语句写法和很多编程语言不太一样
if后面的条件表达式,没有(), 是使用:作为结尾
if/else命中条件后要执行的语句块 使用缩进 而不是大括号
对于多条件分支,不是写作else if 而是elif合体了
缩进和代码块:
代码块 指的是一组放在一起执行的代码.
在 Python 中使用缩进表示代码块. 不同级别的缩进, 程序的执行效果是不同的.
python
# 代码1
a = input("请输入一个整数: ")
if a == "1":
print("hello")
print("world")
# 代码2
a = input("请输入一个整数: ")
if a == "1":
print("hello")
print("world")
注意上述代码的区别.
在代码1 中, print("world") 有一级缩进, 这个语句属于 if 内的代码块, 意味着条件成立, 才执行, 条件不
成立, 则不执行.
在代码2 中, print("world") 没有缩进, 这个语句是 if 外部的代码, 不属于 if 内部的代码块. 意味着条件
无论是否成立, 都会执行33
空语句:
python
输入一个数字 如果数字为1 则打印hello
a = int(input("请输入一个整数:"))
if a == 1:
print("hello")
这个代码也可以等价写成
a = int(input("请输入一个整数:"))
if a != 1:
pass
else:
print("hello")
循环语句:
python
while循环 :
while 条件: 条件为真, 则执行循环体代码.
循环体 条件为假, 则结束循环.
---------------------------------------------
for循环 :
for 循环变量 in 可迭代对象:
循环体
python 的 for 和其他语言不同, 没有 "初始化语句", "循环条件判定语句", "循环变量更新语句", 而是
更加简单,所谓的 "可迭代对象", 指的是 "内部包含多个元素, 能一个一个把元素取出来的特殊变量"
# 代码示例: 打印 1-10
# 使用 range 函数, 能够生成一个可迭代对象. 生成的范围是 [1, 11), 也就是 [1, 10]
for i in range(1, 11):
print(i)
# 代码示例: 打印 2, 4, 6, 8, 10
# 通过 range 的第三个参数, 可以指定迭代时候的 "步长". 也就是一次让循环变量加几.
for i in range(2, 12, 2):
print(i)
# 代码示例: 打印 10-1
# range 的 步长 也可以设定成负数.
for i in range(10, 0, -1):
print(i)
# 代码示例: 求 1 - 100 的和
sum = 0
for i in range(1, 101):
sum += i
print(sum)
continue: 表示结束这次循环, 进入下次循环.
break:表示结束整个循环
7.0 函数
python
语法格式:
创建函数/定义函数
def 函数名(形参列表):
函数体
return 返回值
调用函数/使用函数
函数名(实参列表) // 不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
函数定义并不会执行函数体内容, 必须要调用才会执行. 调用几次就会执行几次
def test1():
print('hello')
# 如果光是定义函数, 而不调用, 则不会执行.
函数必须先定义, 再使用.
# 错误示例:先调用后定义,会报错
test3() # 还没有执行到定义, 就先执行调用了, 此时就会报错.
def test3():
print('hello')
函数参数
在函数定义的时候, 可以在 ( ) 中指定 "形式参数" (简称 形参), 然后在调用的时候, 由调用者把 "实际参数"
(简称 实参) 传递进去.
这样就可以做到一份函数, 针对不同的数据进行计算处理
def calcSum(beg, end):
sum = 0
for i in range(beg, end + 1):
sum += i
print(sum)
calcSum(1, 100)
calcSum(300, 400)
calcSum(1, 1000)
上面的代码中, beg, end 就是函数的形参. 1, 100 / 300, 400 就是函数的实参
函数的返回值
函数的参数可以视为函数的输入,则函数的返回值就可以视为函数的 输出
一个函数中可以有多个 return 语句
# 判定是否是奇数
def isOdd(num):
if num % 2 == 0:
return False
else:
return True
result = isOdd(10)
print(result)
执行到return语句 函数就会立即执行结束,回到调用位置
# 判定是否是奇数
def isOdd(num):
if num % 2 == 0:
return False
return True
result = isOdd(10)
print(result)
#如果num是偶数 则进入if之后 就会触发return False 也就不会继续执行return True
一个函数是可以一次返回多个返回值的. 使用 , 来分割多个返回值
def getPoint():
x = 10
y = 20
return x, y
a, b = getPoint()
就是用一种简洁的语法,把函数返回的两个值,同时赋予两个独立的变量,方便你后续分别使用。
如果只想关注其中部分的返回值 可以使用_来忽略不想要的返回值
def getPoint():
x = 10
y = 20
return x, y
_, b = getPoint()
8.0 变量的作用域
python
变量只能在所在的函数内部生效
在函数 getPoint() 内部定义的 x, y 只是在函数内部生效. 一旦出了函数的范围, 这两个变量就不再生效
了.
def getPoint():
x = 10
y = 20
return x, y
# 必须接收返回值
x, y = getPoint()
print(x, y)
NameError:name 'X'is not defined
在不同的作用域中,允许同名存在的变量
虽然名字相同,实际上是不同的变量
x = 20
def test():
x = 10
print(f'函数内部 x = {x}')
test()
print(f'函数外部 x = {x}')
函数内部 x = 10
函数外部 x = 20 在函数内部的变量,也称为局部变量
不在任何函数内部的变量,也称为全局变量
如果函数内部尝试访问的变量在局部不存在
就会去尝试在全局作用域中查找
x = 20
def test():
print(f'x = {x}')
test()
结果是x=20
如果是想在函数内部,修改全局变量的值
需要使用global关键字声明
x = 20
def test():
global x
x = 10
print(f'函数内部 x = {x}')
test()
print(f'函数外部 x = {x}')
函数内部x = 10
函数外部x = 10
if / while / for 等语句块不会影响到变量作用域
换而言之, 在 if / while / for 中定义的变量, 在语句外面也可以正常使用.
for i in range(1, 10):
print(f'函数内部 i = {i}')
print(f'函数外部 i = {i}')
9.0 函数执行过程
调用函数才会执行函数体代码. 不调用则不会执行.
函数体执行结束(或者遇到 return 语句), 则回到函数调用位置, 继续往下执行
python
def test():
print("执行函数内部代码")
print("执行函数内部代码")
print("执行函数内部代码")
print("1111")
test()
print("2222")
test()
print("3333")
结果:
1111
执行函数内部代码
执行函数内部代码
执行函数内部代码
2222
执行函数内部代码
执行函数内部代码
执行函数内部代码
3333
10.0 链式调用
python
result = isOdd(10)
print(result)
实际上也可以简化写作 print(isOdd(10))
把一个函数的返回值, 作为另一个函数的参数, 这种操作称为 链式调用
11.0 嵌套调用
函数内部还可以调用其他函数 这个动作称为 嵌套调用
python
def test():
print("执行函数内部代码")
print("执行函数内部代码")
print("执行函数内部代码")
一个函数里面可以嵌套调用任意多个函数
函数的嵌套过程是非常灵活的
python
def a():
print("函数 a")
def b():
a()
print("函数 b")
def c():
print("函数 c")
b()
def d():
print("函数 d")
c()
d()
输出也是abcd 体会那个感觉
函数之间的调用关系, 在 Python 中会使用一个特定的数据结构来表示, 称为 函数调用栈 . 每次函数调用,
都会在调用栈里新增一个元素, 称为 栈帧
12.0 函数的递归
按照Java的方式理解就行 和Java差不多
13.0 参数默认值
python
python函数中 可以给形参指定默认值
带有默认值的参数,可以在调用的时候不传参
代码示例:计算两个数字的和
def add(x, y, debug=False):
if debug:
print(f'调试信息: x={x}, y={y}')
return x + y
print(add(10, 20))
print(add(10, 20, True))
此处 debug=False 即为参数默认值. 当我们不指定第三个参数的时候, 默认 debug 的取值即为 False
带有默认值的参数需要放到没有默认值的参数的后面
# 默认参数放在最后
def add(x, y, debug=False):
if debug:
print(f'调试信息: x={x}, y={y}')
return x + y
print(add(10, 20))
这样是会报错的
14.0 关键字参数
python
在调用函数的时候 需要给函数指定实参 一般默认情况下是按照形参的顺序 来依次传递实参的
但是我们也可以通过 关键字参数, 来调整这里的传参顺序, 显式指定当前实参传递给哪个形参
def test(x, y):
print(f'x = {x}')
print(f'y = {y}')
test(x=10, y=20)
test(y=100, x=200)
打印:x=10 y=20 x=200 y=100
三、Python基础语法2
1.0 列表和元组
列表:列表是一种让程序员在代码中批量表示 批量保存数据的方式
元组和列表相比:是非常相似的
只是里列表中放哪些元素可以修改调整
元组中放的是元素创建元组的时候就设定好的 不能修改调整
可以理解为一个是散装 可以随时添加元素 一个是包装,固定的这么多 不能变动了
创建列表:
python
创建列表主要有两种方式. [ ] 表示一个空的列表.
alist = [ ]
alist = list()
print(type(alist))
如果需要往里面设置初始值,可以直接写在[ ]当中
alist = [1, 2, 3, 4]
print(alist)
列表中存放的元素允许是不同的类型 和Java差别比较大
alist = [1, 'hello', True]
print(alist)
访问下标:
python
可以通过下标访问操作符 [ ] 来获取到列表中的任意元素
alist = [1, 2, 3, 4]
print(alist[2])
打印结果是3,下标是从0开始的
通过下标不光能读取元素内容, 还能修改元素的值
alist = [1, 2, 3, 4]
alist[2] = 100
print(alist)
如果下标超出列表有效范围 会抛出异常
alist = [1, 2, 3, 4]
print(alist[100])
因为下标是从 0 开始的, 因此下标的有效范围是 [0, 列表长度 - 1]. 使用 len 函数可以获取到列表的
元素个数.
alist = [1, 2, 3, 4]
print(len(alist))
下标可以取负数 表示倒数第几个元素
alist = [1, 2, 3, 4]
print(alist[3])
print(alist[-1])
alist[-1] 相当于 alist[len(alist) - 1]
切片操作:
python
通过下标操作是一次取出里面的第一个元素
通过切片, 则是一次取出一组连续的元素, 相当于得到一个 子列表
使用 [ : ] 的方式进行切片操作.
list = [1, 2, 3, 4]
print(alist[1:3])
alist[1:3] 中的 1:3 表示的是 [1, 3) 这样的由下标构成的前闭后开区间.
也就是从下标为 1 的元素开始(2), 到下标为 3 的元素结束(4), 但是不包含下标为 3 的元素.
所以最终结果只有 2, 3
切片操作中可以省略前后边界
alist = [1, 2, 3, 4]
print(alist[1:]) # 省略后边界, 表示获取到列表末尾
print(alist[:-1]) # 省略前边界, 表示从列表开头获取
print(alist[:]) # 省略两个边界, 表示获取到整个列表
切片操作还可以指定 "步长" , 也就是 "每访问一个元素后, 下标自增几步"
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(alist[::1])
print(alist[::2])
print(alist[::3])
print(alist[::5])
结果为:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 3, 5, 7, 9]
[1, 4, 7, 10]
[1, 6]
切片操作指定的步长还可以是负数, 此时是从后往前进行取元素. 表示 "每访问一个元素之后, 下标自
减几步"
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(alist[::-1])
print(alist[::-2])
print(alist[::-3])
print(alist[::-5])
如果切片中填写的数字越界了, 不会有负面效果. 只会尽可能的把满足条件的元素过去到.
alist = [1, 2, 3, 4]
print(alist[100:200])
遍历列表元素
python
遍历指的是把元素一个一个的取出来 再分别进行处理
最简单的办法是使用for循环
alist = [1, 2, 3, 4]
for elem in alist:
print(elem)
也可以使用for按照范围生成下标,按下标访问
alist = [1, 2, 3, 4]
for i in range(0, len(alist)):
print(alist[i])
还可以使用 while 循环. 手动控制下标的变化
alist = [1, 2, 3, 4]
i = 0
while i < len(alist):
print(alist[i])
i += 1
新增元素
python
使用 append 方法, 向列表末尾插入一个元素(尾插).
alist = [1, 2, 3, 4]
alist.append('hello')
print(alist)
使用 insert 方法, 向任意位置插入一个元素
alist = [1, 2, 3, 4]
alist.insert(1, 'hello')
print(alist)
#方法就是函数 只不过函数是独立存在的 而方法往往要依附于某个"对象"
像上述代码 alist.append, append就是依附于alist 相当于是 针对alist这个列表
进行尾插操作
查找元素
python
使用 in 操作符, 判定元素是否在列表中存在. 返回值是布尔类型
alist = [1, 2, 3, 4]
print(2 in alist)
print(10 in alist)
使用 index 方法, 查找元素在列表中的下标. 返回值是一个整数. 如果元素不存在, 则会抛出异常.
alist = [1, 2, 3, 4]
print(alist.index(2))
print(alist.index(10))
删除元素
python
使用 pop 方法删除最末尾元素
alist = [1, 2, 3, 4]
alist.pop()
print(alist)
pop 也能按照下标来删除元素
alist = [1, 2, 3, 4]
alist.pop(2)
print(alist)
使用 remove 方法, 按照值删除元素
alist = [1, 2, 3, 4]
alist.remove(2)
print(alist)
连接列表
python
使用 + 能够把两个列表拼接在一起
此处的 + 结果会生成一个新的列表. 而不会影响到旧列表的内容
alist = [1, 2, 3, 4]
blist = [5, 6, 7]
print(alist + blist)
使用 extend 方法, 相当于把一个列表拼接到另一个列表的后面
a.extend(b) , 是把 b 中的内容拼接到 a 的末尾. 不会修改 b, 但是会修改 a.
alist = [1, 2, 3, 4]
blist = [5, 6, 7]
alist.extend(blist)
print(alist)
print(blist)
关于元组:
python
元组的功能和列表相比, 基本是一致的.
元组使用 ( ) 来表示
atuple = ( )
atuple = tuple()
元组不能修改里面的元素, 列表则可以修改里面的元素
因此, 像读操作,比如访问下标, 切片, 遍历, in, index, + 等, 元组也是一样支持的.
但是, 像写操作, 比如修改元素, 新增元素, 删除元素, extend 等, 元组则不能支持
另外, 元组在 Python 中很多时候是默认的集合类型. 例如, 当一个函数返回多个值的时候
def getPoint():
return 10, 20
result = getPoint()
print(type(result)) 返回结果是tuple#这个单词的意思是元组
2.0 字典
字典是一种键值对的结构
啥是键值对? 把 键(key) 和 值(value) 进行一个一对一的映射, 然后就可以根据键, 快速找到值.
python
创建字典
创建一个空的字典. 使用 { } 表示字典.
a = { }
b = dict()
print(type(a))
print(type(b))
也可以在创建的同时指定初始值
键值对之间使用 , 分割, 键和值之间使用 : 分割. (冒号后面推荐加一个空格).
使用 print 来打印字典内容
student = { 'id': 1, 'name': 'zhangsan' }
print(student)
结果是{'id': 1, 'name': 'zhangsan'}
为了代码更规范和美观
在创建字典的时候 往往会把多个键值对 分成多行来书写
student = {
'id': 1,
'name': 'zhangsan'
}
最后一个键值对 后面可以写 也可以不写
student = {
'id': 1,
'name': 'zhangsan',
}
python
查找key
使用 in 可以判定 key 是否在 字典 中存在. 返回布尔值.
student = {
'id': 1,
'name': 'zhangsan',
}
print('id' in student)
print('score' in student)
结果是 true false
使用 [ ] 通过类似于取下标的方式, 获取到元素的值. 只不过此处的 "下标" 是 key. (可能是整数, 也
可能是字符串等其他类型).
student = {
'id': 1,
'name': 'zhangsan',
}
print(student['id'])
print(student['name'])
结果是1 zhangsan
如果 key 在字典中不存在, 则会抛出异常
student = {
'id': 1,
'name': 'zhangsan',
}
print(student['score'])
python
新增/修改元素
使用 [ ] 可以根据 key 来新增/修改 value
如果 key 不存在, 对取下标操作赋值, 即为新增键值对
student = {
'id': 1,
'name': 'zhangsan',
'score': 80
}
student['score'] = 90
print(student)
结果是
{'id': 1, 'name': 'zhangsan', 'score': 90}
如果 key 已经存在, 对取下标操作赋值, 即为修改键值对的值
student = {
'id': 1,
'name': 'zhangsan',
'score': 80
}
student['score'] = 90
print(student)
{'id': 1, 'name': 'zhangsan', 'score': 90}
python
删除元素
使用 pop 方法根据 key 删除对应的键值对
student = {
'id': 1,
'name': 'zhangsan',
'score': 80
}
student.pop('score')
print(student)
{'id': 1, 'name': 'zhangsan'}
python
遍历字典元素
直接使用 for 循环能够获取到字典中的所有的 key, 进一步的就可以取出每个值了
student = {
'id': 1,
'name': 'zhangsan',
'score': 80
}
for key in student:
print(key, student[key])
结果是:
id 1
name zhangsan
score 80
python
取出所有的key 和 value
使用 keys 方student = {
'id': 1,
'name': 'zhangsan',
'score': 80
}
print(student.keys())法可以获取到字典中的所有的 key
结果是:
dict_keys(['id', 'name', 'score'])
使用 values 方法可以获取到字典中的所有 value
student = {
'id': 1,
'name': 'zhangsan',
'score': 80
}
print(student.values())
结果是:
dict_values([1, 'zhangsan', 80])
使用 items 方法可以获取到字典中所有的键值对
student = {
'id': 1,
'name': 'zhangsan',
'score': 80
}
print(student.items())
结果是:
dict_items([('id', 1), ('name', 'zhangsan'), ('score', 80)])
合法的key类型
python
不是所有的类型都可以作为字典的 key.
字典本质上是一个 哈希表, 哈希表的 key 要求是 "可哈希的", 也就是可以计算出一个哈希值
可以使用 hash 函数计算某个对象的哈希值.
但凡能够计算出哈希值的类型, 都可以作为字典的 key
print(hash(0))
print(hash(3.14))
print(hash('hello'))
print(hash(True))
print(hash(())) # ( ) 是一个空的元组
结果是
0
322776226802927619
3597433766221862532
1
8869570264351
列表无法计算哈希值
print(hash([1, 2, 3]))
结果是
print(hash({ 'id': 1 }))
字典也无法计算哈希值
print(hash({ 'id': 1 }))
TypeError: unhashable type: 'dict'
小结
字典也是一个常用的结构. 字典的所有操作都是围绕 key 来展开的.
需要表示 "键值对映射" 这种场景时就可以考虑使用字典
3.0 文件
变量是把数据保存到内存中,如果程序重启/主机重启, 内存中的数据就会丢失.
要想能让数据被持久化存储, 就可以把数据存储到硬盘中. 也就是在 文件中保存
文件路径:
目录之间的分隔符, 可以使用 \ 也可以使用 / . 一般在编写代码的时候使用 / 更方便
文件操作:
但是要想读写文件, 需要先 "打开文件", 读写完毕之后还要 "关闭文件
打开文件:
python
使用内建函数 open 打开一个文件
f = open('d:/test.txt', 'r')
第一个参数是一个字符串, 表示要打开的文件路径
第二个参数是一个字符串, 表示打开方式. 其中 r 表示按照读方式打开. w 表示按照写方式打开. a
表示追加写方式打开.
如果打开文件成功, 返回一个文件对象. 后续的读写文件操作都是围绕这个文件对象展开.
如果打开文件失败(比如路径指定的文件不存在), 就会抛出异常.
关闭文件:
python
使用 close 方法关闭已经打开的文件
f.close()
使用完毕的文件要记得及时关闭!
注意:一个程序能同时打开的文件个数, 是存在上限的.
python
flist = []
count = 0
while True:
f = open('d:/test.txt', 'r')
flist.append(f)
count += 1
print(f'count = {count}')
OSError: [Errno 24] Too many open files: 'd:/test.txt'
如上面代码所示, 如果一直循环的打开文件, 而不去关闭的话, 就会出现上述报错.
当一个程序打开的文件个数超过上限, 就会抛出异常.
注意: 上述代码中, 使用一个列表来保存了所有的文件对象. 如果不进行保存, 那么 Python 内置的垃
圾回收机制, 会在文件对象销毁的时候自动关闭文件.
但是由于垃圾回收操作不一定及时, 所以我们写代码仍然要考虑手动关闭, 尽量避免依赖自动关闭.
写文件:
python
写文件, 要使用写方式打开, open 第二个参数设为 'w'
使用 write 方法写入文件
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
用记事本打开文件, 即可看到文件修改后的内容.
如果是使用 'r' 方式打开文件, 则写入时会抛出异常
f = open('d:/test.txt', 'r')
f.write('hello')
f.close()
使用 'w' 一旦打开文件成功, 就会清空文件原有的数据.
使用 'a' 实现 "追加写", 此时原有内容不变, 写入的内容会存在于之前文件内容的末尾.
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
f = open('d:/test.txt', 'a')
f.write('world')
f.close()
结果是helloworld
针对已经关闭的文件对象进行写操作, 也会抛出异常
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
f.write('world')
读文件:
python
读文件内容需要使用 'r' 的方式打开文件
使用 read 方法完成读操作. 参数表示 "读取几个字符"
f = open('d:/test.txt', 'r')
result = f.read(2)
print(result)
f.close()
结果是:你好
如果文件是多行文本, 可以使用 for 循环一次读取一行.
先构造一个多行文件
f = open('d:/test.txt', 'r')
for line in f:
print(f'line = {line}')
f.close()
结果是
line = 床前明月光
line = 疑是地上霜
line = 举头望明月
line = 低头思故乡
使用 readlines 直接把文件整个内容读取出来, 返回一个列表. 每个元素即为一行.
f = open('d:/test.txt', 'r')
lines = f.readlines()
print(lines)
f.close()
结果是
lines = [line.strip() for line in f.readlines()]
关于中文的处理:
python
打开文件之后, 是容易忘记关闭的. Python 提供了 上下文管理器 , 来帮助程序猿自动关闭文件.
使用 with 语句打开文件.
当 with 内部的代码块执行完毕后, 就会自动调用关闭方法.
使用上下文管理器:
python
打开文件之后, 是容易忘记关闭的. Python 提供了 上下文管理器 , 来帮助程序猿自动关闭文件.
使用 with 语句打开文件.
当 with 内部的代码块执行完毕后, 就会自动调用关闭方法.
with open('d:/test.txt', 'r', encoding='utf8') as f:
lines = f.readlines()
print(lines)
4.0 使用库
库就是是别人已经写好了的代码, 可以让我们直接拿来用
按照库的来源, 可以大致分成两大类
标准库: Python 自带的库. 只要安装了 Python 就可以直接使用.
第三方库: 其他人实现的库. 要想使用, 需要额外安装.
标准库:Python 自身内置了非常丰富的库
在 Python 官方文档上可以看到这些库的内容. https://docs.python.org/3.10/library/index.html
python
简单来说, 主要是这些部分:
内置函数 (如 print, input 等)
内置类型 (针对 int, str, bool, list, dict 等类型内置的操作).
文本处理
时间日期
数学计算
文件目录
数据存储 (操作数据库, 数据序列化等).
加密解密
操作系统相关
并发编程相关 (多进程, 多线程, 协程, 异步等).
网络编程相关
多媒体相关 (音频处理, 视频处理等)
图形化界面相关
.......
使用import导入模块
python
import [模块名]
所谓 "模块" , 其实就是一个单独的 .py 文件.
使用 import 语句可以把这个外部的 .py 文件导入到当前 .py 文件中, 并执行其中的代码
第三方库:
第三方库就是别人已经实现好了的库, 我们可以拿过来直接使用.
虽然标准库已经很强大了, 但是终究是有限的. 而第三方库可以视为是集合了全世界 Python 程序猿的智
慧, 可以说是几乎无穷无尽.
问题来了, 当我们遇到一个需求场景的时候, 如何知道, 该使用哪个第三方库呢?
当我们确定了该使用哪个第三方库之后, 就可以使用 pip 来安装第三方库了.
使用 pip:
pip 是 Python 内置的 包管理器.
所谓 包管理器 就类似于我们平时使用的手机 app 应用商店一样.
第三方库有很多, 是不同的人, 不同的组织实现的. 为了方便大家整理, Python 官方提供了一个网站
PyPI https://pypi.org/, 来收集第三方库.
python
import os
inputPath = input('请输入待搜索路径: ')
pattern = input('请输入待搜索关键词: ')
for dirpath, dirnames, filenames in os.walk(inputPath):
for f in filenames:
if pattern in f:
print(f'{dirpath}/{f}')
其他大佬写好的第三方库也会申请上传到 PyPI 上.
这个时候就可以方便的使用 pip 工具来下载 PyPI 上的库了
pip 在我们安装 Python 的时候就已经内置了. 无需额外安装.
pip 是一个可执行程序, 就在 Python 的安装目录中.
打开 cmd, 直接输入 pip. 如果显示以下帮助信息, 说明 pip 已经准备就绪