1、python 被称为胶水语言,可以跟各个代码能一块儿使用
爬虫、数据分析
web全栈开发、数据科学方向、人工智能的机械学习和深度学习、自动化运维、爬虫、办公自动化
python是跨平台的,python是解释型语言,不需要编译,python是面向对象的语言
# print()可以输出数字、字符串、含有运算符的表达式
# print()可以将内容输出到显示器、文件
# print()输出形式换行、不换行
# 字符串可以使用单引号、双引号、三引号。目的是为了告诉计算机,不需要经行额外的处理
print(1)
print(3 + 2)
print('hello world')
print('hello', 'world', 'python') # 不换行输出
# print() 输出到文件中,注意点 1、 所指定的盘符要存在。2、使用file=xx
fp = open('C:/Users/wb_zhouwei/PycharmProjects/text.txt', 'a+') # 文件不存在就创建,文件存在就在文件内容最后面继续添加内容
print('hello world', file=fp)
fp.close()
# 转义字符
# 就是反斜杠+想要实现功能的首字母
# 换行 \n
print('hello\nworld')
# 水平制表符 \t 每四个字母为一个制表位,正好占满,新开一个制表位,没占满补齐
print('hello\tworld')
print('hell\tworld')
# 回车 \r 用后面的覆盖前面的
print('helloo\rworld')
# 退格 \b 往前回退一个字母位
print('hello\bworld')
# \' \\ \"
print('周凯说:\'黄亮是傻逼\'')
# 原字符 不希望字符串中的转义字符起作用,就使用元字符,就是在字符串之前加r或R
print(r'及方式连接方式')
# print(r'技术的困窘\') 注意:字符串最后不能是单数个反斜杠,但是可以是双数个
8 bit 表示一个字节 1 byte
1024 byte = 1 KB
MB GB TB
二进制=>ascll 码表 =>统一编码 Unicode =>utf-8
import keyword
print(keyword.kwlist)
输出结果:
['False', 'None', 'True', '__peg_parser__', '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']
以上均为保留字
变量,函数,类,模块和其他对象的起的名字就叫标识符
规则:
字母,数字,下划线
不能以数字开头
不能是保留字
严格区分大小写
name = ‘玛丽亚’
变量有三部分组成
标识:表示对象所从出的内存地址,使用内置函数id(obj)来获取
类型:表示的时对象的数据类型,使用内置函数type(obj)来获取
值:表示对象所存储的具体数据,使用print(obj)可以将值进行打印输出
name = '玛丽亚'
print(name)
print('标识', id(name))
print('类型', type(name))
print('值', name)
name = '楚留冰'
print(name)
print('标识', id(name))
print('类型', type(name))
print('值', name)
玛丽亚
标识 2084983730320
类型 <class 'str'>
值 玛丽亚
楚留冰
标识 2084983731568
类型 <class 'str'>
值 楚留冰
当多次赋值之后,变量名会指向信的空间
整数类型->int
浮点数类型->float
布尔类型->bool
字符串类型->str
integer 简写为int 表示正数、负数和零
默认为十进制
二进制->以0b开头
八进制->以0o开头
十六进制->以0x开头
# 表示正数、负数、0
n1 = 90
n2 = - 76
n3 = 0
print(n1, type(n1))
print(n2, type(n2))
print(n3, type(n3))
# 正数可以表示二进制、八进制、十进制、十六进制
print('十进制', 118)
print('二进制', 0b10101111) # 二进制以0b开头
print('八进制', 0o176) # 八进制以0o开头
print('十六进制', 0xa8624) # 十六进制以0x开头
浮点数分为整数部分和小数部分
浮点数存储不精确性
使用浮点进行计算时,可能会出现小数不确定的情况
原因:采用二进制进行存储的,导致精度不准确
n1= 1.1
print(n1 + 2.2) # 3.3000000000000003
print(n1 + 2.1) # 3.2
解决方案
导入模块decimal
from decimal import Decimal
print(Decimal('1.1') + Decimal('2.2'))
用来表示真或假的值
True表示真,False表示假
布尔值可以转化为整数
True = 1
False= 0
f1 = True
f2 = False
print(f1, type(f1))
print(f2, type(f2))
print(f1 + 1) # 2
print(f2 + 1) # 1
又被称为不可变的字符序列
可以使用单引号’ ‘双引号" “三引号”’ '“或”“” “”"来定义
单引号和双引号定义的字符串必须在一行
三引号定义的字符串可以分布在连续的多行
str1 = '人生苦短,及时行乐'
str2 = "人生苦短,及时行乐"
str3 = """人生苦短,
及时行乐"""
print(str1, type(str1))
print(str2, type(str2))
print(str3, type(str3))
# 人生苦短,及时行乐
# 人生苦短,及时行乐
# 人生苦短,
# 及时行乐
为什么需要数据类型转换
将不同数据类型的数据拼接在一起
str() 也可以使用引号转换
int()
1、文字类和小数类的字符串,无法转换
2、浮点数转换为整数,抹零取整
float()
1、文字类的字符串无法转换成浮点数
2、整数转换成浮点数,末尾多加.0
name = '张三'
age = 20
print(type(name), type(age)) # 说明name与age的类型不相同
print('我叫' + name + ',今年' + str(age) + '岁') # 将int类型通过str()函数转成了str类型
print('-------------------str()将其他类型转成str类型----------------------')
a = 10
b = 198.12
c = False
print(type(a), type(b), type(c))
print(str(a), type(str(a)))
print(str(b), type(str(b)))
print(str(c), type(str(c)))
print('-------------------int()将其他类型转成int类型----------------------')
s1 = '128'
f1 = 98.7
s2 = '76.77'
ff = True
s3 = 'hello'
print(type(s1), type(f1), type(s2), type(ff), type(s3))
print(int(s1), type(int(s1)))
print(int(f1), type(int(f1)))
# print(int(s2), type(int(s2))) 报错 字符串为小数
print(int(ff), type(int(ff)))
# print(int(s3), type(int(s3))) 报错 字符串必须是数字串(整数),非数字串是不允许转换的
print('-------------------float()将其他类型转成float类型----------------------')
s1 = '128.98'
s2 = '76'
s3 = 'hello'
ff = True
i = 98
print(type(s1), type(s2), type(s3), type(ff), type(i))
print(float(s1), type(float(s1)))
print(float(s2), type(float(s2)))
print(float(ff), type(float(ff)))
# print(float(s3), type(float(s3))) 字符串中的数据如果为非数据串,则不允许转换
print(float(i), type(float(i)))
注释是给人看的,注释内容会被python解释器忽略
单行注释 #
多行注释 并没有单独的多行注释标记,将一对三引号之间的代码成为多行注释
中文编码声明注释 再文件开头加上中文声明注释,用以指定源码文件的编码格式 #coding:gbk (python3不用)
# 输出功能 单行注释
print('hello')
"""
这就是
多行注释
"""
作用:接受来自用户的输入
返回值类型:输入值的类型str
值的存储:使用=对输入的值进行存储
# 输入函数input
present = input('大圣想要什么礼物呢?')
print(present, type(present))
# 大圣想要什么礼物呢?ding
# ding
作业:
# 从键盘录入两个整数,计算整数的和
a = input('请输入第一个整数:')
b = input('请输入第二个整数:')
print(int(a) + int(b))
# 请输入第一个整数:10
# 请输入第二个整数:20
# 30
# 优化:
a = int(input('请输入第一个整数:'))
b = int(input('请输入第二个整数:'))
print(a + b)
加(+)、减(-)、乘(*)、除(/)、整除(//)
print(1 + 1) # 加法运算 2
print(2 - 1) # 减法运算 1
print(2 * 4) # 乘法运算 8
print(1 / 2) # 除法运算 0.5
print(11 // 2) # 整除运算 5
print(9 / -4) # -2.25
print(9 // 4) # 2
print(-9 // -4) # 2
print(9 // -4) # -3
print(-9 // 4) # -3
# 一正一负的整除公式,向下取整
所有的整除公式,都是向下取整
取余 %
print(11 % 2) # 取余运算 1 11-2*5 = 1
print(9 % -4) # -3 9-(-4)*(-3) = -3
print(-9 % 4) # 3 -9-4*(-3) = 3
# 余数 = 被除数-除数*商
余数 = 被除数-除数*商(整除的商)
幂运算 **
print(2 ** 3) # 2的3次方 8
右到左:将右边的值赋值给左边
支持链式赋值: a=b=c=20
支持参数赋值:+=、-+、*=、/=、//=、%=
支持系列解包赋值:a,b,c=20,30,40 **注意:**左右两边个数要相同
i = 3 + 4
print(i)
print('--------支持链式赋值-----------')
a = b = c = 20 # a b c 的引用都指向同一个对象
print(a, id(a))
print(b, id(b))
print(c, id(c))
print('-------------------支持参数赋值------------------------')
a = 20
a += 30
print(a) # 50
a -= 10
print(a) # 40
a *= 2
print(a, type(a)) # 80
a /= 3
print(a, type(a)) # 26.666666666666668
a //= 2
print(a, type(a)) # 13.0
a %= 3
print(a) # 1.0
print('-------------------支持系列解包赋值------------------------')
a, b, c = 20, 30, 40
print(a, b, c) # 20 30 40
print('----------交换两个变量的值----------')
a, b = 10, 20
print('交换之前:', a, b) # 交换之前: 10 20
# 交换
a, b = b, a
print('交换之后:', a, b) # 交换之后: 20 10
定义:对变量或者表达式的结果进行大小,真假等比较 结果为boolean类型
< 、> 、<= 、>=、 !=
== 对象value的比较
is,is not 对象id的比较
a, b = 10, 20
print('a>b吗?', a > b) # False
print('a, a < b) # True
print('a<=b吗?', a <= b) # True
print('a>=b吗?', a >= b) # False
print('a==b吗?', a == b) # False
print('a!=b吗?', a != b) # True
"""
= 称为赋值运算符 == 称为比较运算符
一个变量有三个部分组成,标识,类型,值
== 比较的是两个对象的值
比较对象的标识使用的是 is is not
"""
a = 10
b = 10
print(a == b) # True 说明a与b的value,相等
print(a is b) # True 说明a与b的id标识,相等
print(a is not b) # False
lst1 = [11, 22, 33, 44]
lst2 = [11, 22, 33, 44]
print(lst1 == lst2) # True
print(lst1 is lst2) # False
print(lst1 is not lst2) # True
print(id(lst1)) # 3100263766848
print(id(lst2)) # 3100263605248
and 并且
or 或者
ont 取反
in
not in
# 布尔运算符
print('--------------------and 并且-------------------------')
a, b = 10, 20
print(a == 10 and b == 20)
print(a == 10 and b < 20)
print(a != 10 and b == 20)
print(a != 10 and b != 20)
print('--------------------or 或者-------------------------')
print(a == 10 or b == 20)
print(a == 10 or b < 20)
print(a != 10 or b == 20)
print(a != 10 or b != 20)
print('--------------------not 布尔类型的操作数取反-------------------------')
f = True
f2 = False
print(not f)
print(not f2)
print('--------------------in 包含-------------------------')
s = 'helloworld'
print('w' in s)
print('k' in s)
print('w' not in s)
print('k' not in s)
位与 & 对应数位都是1,结果才为1,否则为0
位或 | 对应数位都是0,结果才是0,否则为1
左移运算符 << 高位溢出舍弃,地位补0
右移运算符 >> 低位溢出舍弃,高位补0
print(4 & 8) # 0 # 按位& 同为1时结果为1,否则为0
print(4 | 8) # 12 # 按位| 同为0时结果为0,否则为1
print(4 << 1) # 8
print(4 >> 1) # 2
**
*,/,//,%
+,- 算术运算符先算乘除,再算加减,有幂运算最先算
<<,>>
&
| 位运算
<,>,<=,>=,==,!= 比较运算符
and
or 布尔运算符
= 赋值运算符
右括号先算括号里面的
总结:
() 、算数运算、位运算、比较运算、布尔运算、赋值运算
顺序结构、选择结构、循环结构
从上往下依次执行
python中一切皆对象,所有对象都有一个布尔值
获取对象的布尔值
使用内置函数bool()
以下对象的布尔值为False
False
数值0
None
空字符串
空列表
空元组
空字典
空集合
# 测试对象的布尔值
print(bool(False)) # False False
print(bool(0)) # False 数值0
print(bool(0.0)) # False 数值0
print(bool(None)) # False None
print(bool('')) # False 空字符串
print(bool("")) # False 空字符串
print(bool([])) # False 空列表
print(bool(list())) # False 空列表
print(bool(())) # False 空元组
print(bool(tuple())) # False 空元组
print(bool({})) # False 空字典
print(bool(dict())) # False 空字典
print(bool(set())) # False 空集合
print('---------------------其他对象的布尔值均为True-------')
print(bool(18)) # True
print(bool(True)) # True
print(bool('hello')) # True
主要目的:可以让if后面直接跟非布尔值(对象)
age = int(input('请输入您的年龄:'))
if age:
print(age)
else:
print('年龄不合法!')
# 请输入您的年龄:0
# 年龄不合法!
又称为选择结构
语法结构
if 条件表达式 :
条件执行体
money = 1000
i = int(input('请输入取款金额!'))
if money >= i:
money -= i
print('取款成功,余额为:', money)
if 条件表达式 :
条件执行体1
else:
条件执行体2
# 从键盘录入一个整数,判断是奇数还是偶数
s = int(input('请输入一个整数'))
if s % 2 == 1:
print(s, '该数值为奇数')
else:
print(s, '该数值为偶数')
if 条件表达式:
条件执行体1
elif 条件表达式:
条件执行体2
else:
条件执行体3
'''
多分支结构,多选一
从键盘录入一个整数 成绩
90-100 A
80-89 B
70-79 C
60-69 D
0-59 E
小于0或大于100 为非法数据
'''
score = int(input('请输入一个成绩:'))
if 90 <= score <= 100:
print('A')
elif 80 <= score <= 89:
print('B')
elif 70 <= score <= 79:
print('C')
elif 60 <= score <= 69:
print('D')
elif 0 <= score <= 59:
print('E')
else:
print('成绩输入有误!')
数学比较,只有python能够这样写
条件表达式是if…else…的简写
语法结构:
x if 判断条件 else y
运算规则:
判断条件为True,条件表达式的返回值为x,否则条件表达式的返回值为False
'''从键盘录入两个整数,比较两个整数的大小'''
num_a = int(input('请输入第一个整数'))
num_b = int(input('请输入第一个整数'))
print('大的整数为:', num_a if num_a > num_b else num_b)
pass语句
语句什么都不做,只是一个占位符,用在语法上需要的地方
什么时候使用:
先搭建语法结构,还没想好代码怎么写的时候
哪些语句一起使用:
if语句的条件执行体
for-in语句的循环体
定义函数时的函数体
# pass 语句什么都不做,只是一个占位符,用到需要写语句的地方
answer = input('您是会员吗?y/n')
if answer == 'y':
pass
else:
pass
主要目的:可以让if后面直接跟非布尔值
age = int(input('请输入您的年龄:'))
if age:
print(age)
else:
print('年龄不合法!')
# 请输入您的年龄:0
# 年龄不合法!
内置函数range()、print()、input(),内置函数时不需要导包,直接可以使用的函数
range()函数:
用于生成一个整数序列
创建range对象的三个方式
range(stop) # 创建一个[0,stop)之间的整数序列,步长为1
range(start,stop)# 创建一个[start,stop)之间的整数序列,步长为1
range(start,stop,step)# 创建一个[start,stop)之间的整数序列,步长为step
返回值是一个迭代器对象
range类型的有点:不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的,因为只需要存储start,stop和step,只有当用到range对象时,才会去计算序列中的相关元素
in与not in可以判断整数序列中是否存在指定的整数
# 第一种创建方式
r = range(10) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 默认cong0开始,步长为1
print(r) # range(1,10)
print(list(r)) # 用于查看range对象中的整数序列-->list是列表的意思
# 第二种创建方式
r = range(1, 10) # 制定了起始值,从1开始,到10结束(不包含10),默认步长为1
print(list(r)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 第三种方式
r = range(1, 10, 2)
print(list(r)) # [1, 3, 5, 7, 9]
# 判断指定的数再序列中是否存在
print(10 in r) # False
print(10 not in r) # True
print(9 in r) # True
语法结构:
while 条件表达式:
条件执行体(循环体)
a = 1
while a < 10:
print(a)
a += 1
# 计算0到4之间的累加和
'''
1、初始化变量
2、判断条件
3、条件执行体(循环体)
4、改变变量
总结:初始化的变量与条件判断的变量与改变的变量为统一个
'''
a = 0
sum = 0 # 用于存储累加的值
while a < 5:
sum += a
a += 1
print('和为:', sum)
# 计算1到100之间的偶数和
a = 1
sum = 0
while a <= 100:
if a % 2 == 0: #可以改进为if not bool(a%2): 数值0为False
sum += a
a += 1
print(sum) #2550
in表达从字符串、序列中依次取值,又称为遍历
for-in便利的对象必须是可迭代对象
语法结构:
for 自定义的变量 in 可迭代对象:
循环体
循环体内不需要访问自定义变量时,可以将自定义变量代替为下划线
for item in 'Python':
print(item)
# range()产生一个整数序列,-->也是一个可迭代对象
for i in range(10):
print(i)
# 如果在循环体中,不需要自定义变量,可用_代替自定义变量
for _ in range(5):
print('人生几何')
print('使用for计算1到100的偶数和')
sum = 0
for i in range(1, 101):
if not bool(i % 2):
sum += i
print(sum)
# 输出100到999之间的水仙花数
for item in range(100, 1000):
ge = item % 10
shi = item // 10 % 10
bai = item // 100
if item == ge ** 3 + shi ** 3 + bai ** 3:
print(item)
break用于结束整个循环结构,通常与分支结构if一起使用
continue用于结束当前循环,进入下次循环,通常与分支结构if一起使用
else 分支结构中,if条件表达式不成立时执行else
如果循环语句正常结束(没有碰到break)时执行else语句**
# for循环
for item in range(3):
pwd = input('请输入密码:')
if pwd == '8888':
print('密码正确!')
break
else:
print('密码不正确!')
else:
print('您今日的次数已经用完,请明天再试')
# while循环
a = 0
while a < 3:
pwd = input('请输入密码:')
if pwd == '8888':
print('密码输入正确!')
break
else:
print('密码输入错误!')
a += 1
else:
print('您今日的次数已经用完,请明天再试')
# 输出三行四列的矩形
for i in range(3):
for j in range(4):
print('*', end='\t') # 不换行输出
print()
执行结果:
* * * *
* * * *
* * * *
# 打印99乘法表
for i in range(1, 10):
for j in range(1, i + 1):
a = i * j
print(str(i) + '*' + str(j) + '=' + str(a), end='\t') # 不换行输出
print()
二重循环中的break和continue用于控制本层的循环 即为就近原则
最多别超过三层
变量可以存储一个元素,而列表是一个”大容器“可以存储N多个元素,程序可以方便地对这些数据进行整体操作
列表相当于其他语言的数组 存的内容不一定是同一个类型
a = 10 # 变量存储的是一个对象的引用
# 列表创建方式一
lst = ['hello', 'world', 98]
# 列表创建方式二
lst = list(['hello', 'world', 98])
print(id(lst)) # 指得是列表本身的id 列表中的每个空间存的是对象的内存地址
print(type(lst))
创建方式
lst = [‘大圣’,‘金克拉撒旦’]
lst = list([‘大圣’,‘金克拉撒旦’])
列表的特点
列表元素按顺序有序排序 第一个放的排在第一个
索引映射唯一个数据 从左往右为顺序,从0开始依次递增;从右往左为倒序,从-1开始依次递减
列表可以存储重复的数据
任意数据类型混存
根据需要动态分配和回收内存
获取列表中指定元素的索引
获取列表中指定索引的元素
# 获取列表中指定元素的索引
lst = ['hello', 'world', 98, 'hello']
print(lst.index('hello')) # 0 如果列表中有相同元素,只返回列表中相同元素的第一个元素的索引
# print(lst.index('python')) 查找不存在的元素,回抛出异常ValueError
print(lst.index('hello', 1, 4)) # 从索引[1,4)之间查找'hello'元素 左闭右开
# 获取列表中指定索引的元素
lst2 = ['hello', 'world', 98, 'hello', 'world', 234]
print(lst2[2])
print(lst2[-3])
# print(lst2[10]) # IndexError: list index out of range 索引超出范围会报错
语法格式:列表名[start : stop : step] 左闭右开
切片结果:原列表片段的拷贝
切片的范围:[start : stop]
step默认为1:可简写为[start : stop]
step为正数:从start开始往后计算切片
step为负数:从start开始计算往前切片
lst = [10, 20, 30, 40, 50, 60, 70, 80]
# start =1 ,stop = 6,step =1
# print(lst[1:6:1])
print('原列表', id(lst))
lst2 = lst[1:6:1]
print('切片得到的列表', id(lst2)) # 切片得到新的列表
# 默认步长为1
print(lst[1:6]) # [20, 30, 40, 50, 60]
print(lst[1:6:]) # [20, 30, 40, 50, 60]
print(lst[1:6:2]) # [20, 40, 60]
# 省略start
print(lst[:6:2]) # [10, 30, 50]
# 省略stop
print(lst[1::2]) # [20, 40, 60, 80]
print('______________________步长为负数的情况________________________')
print('原列表', lst)
print(lst[::-1]) # [80, 70, 60, 50, 40, 30, 20, 10]
# start = 7 stop省略 step= -1
print(lst[7::-1]) # [80, 70, 60, 50, 40, 30, 20, 10]
# start = 6 stop =0 step =-2
print(lst[6:0:-2]) # [70, 50, 30]
判断指定元素在列表中是否存在
元素 in 列表名
元素 not in 列表名
列表元素的遍历
for 迭代变量 in列表名 :
操作
print('p' in 'python') # True
lst = [10, 20, 'python', 'hello']
print(10 in lst) # True
print(100 in lst) # False
print('p' in lst) # False
print('-----------------遍历列表------------------------')
for item in lst:
print(item)
append() 在列表末尾添加一个元素
extend() 在列表末尾添加至少一个元素
insert() 在列表的任意位置上插入一个元素(指定位置添加元素)
切片 在列表的任意位置添加至少一个元素
lst = [10, 20, 30]
print('添加元素之前', lst, id(lst))
lst.append(40)
print('添加元素之后', lst, id(lst)) # [10, 20, 30, 40]
lst2 = ['hello', 'world']
# lst.append(lst2)
# print(lst) # [10, 20, 30, 40, ['hello', 'world']] lst2作为一个元素添加到列表当额末尾
lst.extend(lst2)
print(lst) # [10, 20, 30, 40, 'hello', 'world'] 在列表末尾添加至少一个元素
# 在任意位置上插入一个元素
lst.insert(1, 90)
print(lst) # [10, 90, 20, 30, 40, 'hello', 'world']
# 切片添加多个元素
lst3 = [True, False, 'hello']
lst[1:] = lst3
print(lst) # [10, True, False, 'hello']
remove() 一次删除一个元素,重复元素只删除第一个,元素不存在抛出ValueError
pop() 删除一个指定索引位置上的元素,指定索引不存在抛出IndexError,不指定索引则默认删除列表中最后一个元素
切片 一次至少删除一个元素
clear() 清空列表
del 删除列表
lst = [10, 20, 30, 40, 50, 60, 30]
lst.remove(30)
print(lst) # [10, 20, 40, 50, 60, 30] 从列表中移除一个元素,如果有重复元素,只移除第一个元素,如果元素不存在,ValueError
lst.pop(1)
print(lst) # [10, 40, 50, 60, 30] 移除指定索引位置的元素,索引超出IndexError,pop后面不指定参数,默认删除列表最后一个元素
print('----------------切片操作:删除至少一个元素,但是将产生一个新的操作-----------------------')
new_lst = lst[1:3]
print(new_lst) # [40, 50]
'''不产生新的列表对象,而是删除原列表的内容'''
lst[1:3] = []
print(lst) # [10, 60, 30]
'''清除列表中的所有元素'''
lst.clear()
print(lst) # []
'''del语句将删除列表对象'''
del lst
print(lst) # NameError: name 'lst' is not defined 名字没有定义对象
为指定索引的元素赋予一个新值
为指定的切片赋予多个新值
lst = [10, 20, 30, 40]
# 一次修改一个值
lst[2] = 100
print(lst) # [10, 20, 100, 40]
lst[1:3] = [300, 400, 500, 600]
print(lst) # [10, 300, 400, 500, 600, 40] 将中间的20,100,替换成了300,400,500,600
常见的两种方式
调用sort()方法,列表中的所有元素默认按从小到大排序,可以指定reverse = True,进行降序排序
调用内置函数sorted(),可以指定reverse = True,进行降序排序,原列表不发生改变
lst = [20, 40, 58, 10, 98, 54]
print('排序前的内容', lst, id(lst))
# 调用列表对象的sort方法,默认是升序
lst.sort()
print('排序后的列表', lst, id(lst))
# 通过指定参数,将列表中的元素进行降序排序
lst.sort(reverse=True) # reverse =True 表示降序 reverse = False 表示升序
print(lst)
print('---------------使用内置函数sorted()对列表进行排序,将产生一个新的列表')
lst2 = [20, 40, 58, 10, 98, 54]
new_lst = sorted(lst)
print(lst2) # [20, 40, 58, 10, 98, 54]
print(new_lst) # [10, 20, 40, 54, 58, 98]
# 指定关键字参数,实现列表的元素的降序排序
desc_lst = sorted(lst2, reverse=True)
print(desc_lst)# [98, 58, 54, 40, 20, 10]
即生成列表的公式
# [i for i in range(1,10)]
lst = [i * i for i in range(1, 10)]
print(lst) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
lst2 = [i * 2 for i in range(1, 6)]
print(lst2) # [2, 4, 6, 8, 10]
python内置的数据结构之一,与列表一样是一个可变序列
以键值对的方式存储数据,字典是一个无序的序列(存放无序)
scores={‘张三’:100,‘李四’:98,‘王五’:45}
存放原理:对key进行hash计算,计算完的值就是存放的位置,所以key必须是不可变序列(例如:字符串,整数序列)
**字典的实现原理:**字典的实现原理与查字典类似,查字典是先根据部首或拼音查找汉字对应的页码,python中的字典是根据key查找value所在的位置
最常使用的方式:使用花括号
scores={'张三':100,'李四':98,'王五':45}
使用内置函数dict()
dict(name ='jack',age = 20)
# 字典的创建方式
'''使用{}创建字典'''
scores = {'张三': 100, '李四': 98, '王五': 45}
print(scores) # {'张三': 100, '李四': 98, '王五': 45}
print(type(scores)) #
'''第二种创建方式dict()'''
student = dict(name='jack', age=20)
print(student) # {'name': 'jack', 'age': 20}
# 空字典
d = {}
print(d) # {}
scores['张三']
scores.get('张三')
[]如果不存在指定的key,抛出keyError异常
get()方法取值,如果不存在指定的key,并不会抛出keyError而是返回None,可以通过参数设置默认的value,以便指定的key不存在时返回
# 获取字典中的值
scores = {'张三': 100, '李四': 98, '王五': 45}
'''第一种方法,使用[]'''
print(scores['张三']) # 100
# print(scores['陈六'])# KeyError: '陈六'
'''第二种方法,使用get()方法'''
print(scores.get('张三')) # 100
print(scores.get('陈六')) # None
print(scores.get('麻七', 99)) # 99 在查找'麻七'指定的value不存在时,提供的一个默认值
in、not in
'''key的判断'''
scores = {'张三': 100, '李四': 98, '王五': 45}
print('张三' in scores) # True
print('张三' not in scores) # False
del scores[‘张三’]
# 删除指定的字典元素(键值对)
scores = {'张三': 100, '李四': 98, '王五': 45}
del scores['张三']
print(scores) # {'李四': 98, '王五': 45}
scores.claer() # 字典元素的清空操作
print(scores)# {}
scores[‘jack’]= 90
# 新增字典元素
scores = {'张三': 100, '李四': 98, '王五': 45}
scores['jack'] = 90
print(scores) # {'李四': 98, '王五': 45, 'jack': 90}
# 修改操作
scores['jack'] = 100
print(scores) # {'李四': 98, '王五': 45, 'jack': 100}
keys() 获取字典中所有key
values() 获取字典中所有value
items() 获取字典中所有key,value对
scores = {'张三': 100, '李四': 98, '王五': 45}
# 获取所有的key
keys = scores.keys()
print(keys) # dict_keys(['张三', '李四', '王五'])
print(type(keys)) #
print(list(keys)) # ['张三', '李四', '王五'] 通过内置的list()函数将keys转换成列表格式
# 获取所有的值value
values = scores.values()
print(values) # dict_values([100, 98, 45])
print(type(values)) #
print(list(values)) # [100, 98, 45] 通过内置的list()函数将keys转换成列表格式
# 获取所有的键值对
items = scores.items()
print(items) # dict_items([('张三', 100), ('李四', 98), ('王五', 45)])
print(type(items)) #
print(list(items)) # [('张三', 100), ('李四', 98), ('王五', 45)] 转换之后的列表元素是由元组组成
for item in scores:
print(item)
# 字典元素的遍历
scores = {'张三': 100, '李四': 98, '王五': 45}
for item in scores:
print(item, scores.get(item), scores[item])
'''
张三 100 100
李四 98 98
王五 45 45
'''
字典中的所有的元素都是一个key-value对,key不允许重复,value可以重复
重点中的元素时无序的
字典中的key必须是不可变对象
字典也可以根据需要动态的伸缩
字典会浪费较大的内存,是一种用空间换时间的数据结构
d = {'name': '张三', 'name': '李四'}
print(d) # {'name': '李四'} key不允许重复,会覆盖
d = {'name': '张三', 'nikename': '张三'}
print(d) # {'name': '张三', 'nikename': '张三'}
lst = [10, 20, 30]
lst.insert(1, 100)
print(lst) # [10, 100, 20, 30] 字典无法做到此操作
d = {lst: 100}
print(d) # TypeError: unhashable type: 'list' 列表为可变对象,不可以作为key
内置函数zip()
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表
可迭代表示可以遍历
items = ['Fruits', 'Books', 'Others']
prices = [96, 78, 89, 100, 200, 120]
lst = zip(items, prices)
print(list(lst)) # [('Fruits', 96), ('Books', 78), ('Others', 89)]
d = {item.upper(): price for item, price in zip(items, prices)} # upper()表示转换成大写
print(d) # {'FRUITS': 96, 'BOOKS': 78, 'OTHERS': 89}
当两个列表的长度不相等时,zip()函数会以短的那个作为基准压缩打包
字典生成式:d={item:price for item,price in zip(items,prices)}
python内置的数据结构之一,是不可变序列
不可变序列:字符串、元组
不可变序列没有增删改操作
可变序列:列表、字典
可变序列可以对序列执行增删改操作,对象的地址不会发生更改
'''不可变序列 可变序列'''
'''可变序列:列表、字典'''
lst = [10, 20, 30]
print(lst, id(lst)) # [10, 20, 30] 3147123252992
lst.append(40)
print(lst, id(lst)) # [10, 20, 30, 40] 3147123252992
'''不可变序列:字符串、元组'''
s = 'hello'
print(s, id(s)) # hello 3118496028080
s = s + 'world'
print(s, id(s)) # helloworld 3118498180400
t=('python','张三',90)
t=tuple(('python','张三',90))
只包含一个元组的元素需要用逗号和小括号
t=( 10, )
'''第一种创建方式'''
t = ('python', 'hello', 90)
print(t, type(t)) # ('python', 'hello', 90)
t2 = 'python', 'hello', 98
print(t2, type(t2)) # ('python', 'hello', 98) 一个元组多个元素时,可以省略小括号
'''第二种创建方式'''
t = tuple(('python', 'hello', 90))
print(t, type(t)) # ('python', 'hello', 90)
t3 = (10)
print(t3, type(t3)) # 10
t = (10,)
print(t, type(t)) # (10,) 当元组中只有一个元素时,必须要有小括号和逗号,否则为该元素本身的数据类型
'''空列表的常见方式'''
lst = []
lst1 = list()
print('空列表', lst, lst1) # 空列表 [] []
'''空字典的常见方式'''
d = {}
d = dict()
print('空字典', d, d2) # 空字典 {} {}
'''空元组的常见方式'''
t4 = ()
t5 = tuple()
print('空元组', t4, t5) # 空元组 () ()
在多任务环境下,同时操作对象是不需要加锁,因此,在程序中尽量使用不可变序列
(多线程)
注意事项:
元组中存储的是对象的引用(深拷贝与浅拷贝)
a)如果元组中对象本身为不可变对象,则不能在引用其他对象
b)如果元组中的对象是可变对象,则可变对象的引用不允许改变,但是数据可以改变
t = (10, [20, 30], 9)
print(t) # (10, [20, 30], 9)
print(type(t)) #
print(t[0], type(t[0]), id(t[0])) # 10 2983042837072
print(t[1], type(t[1]), id(t[1])) # [20, 30] 2983080812480
print(t[2], type(t[2]), id(t[2])) # 9 2983042837040
'''尝试将t[1]修改为100'''
# 元组是不允许修改元素的
# t[1] = 100 # TypeError: 'tuple' object does not support item assignment
'''由于[20,30]咧白哦,而列表是可变序列,所有可以对列表中的数据进行修改,而列表的内存地址不变'''
t[1].append(99)
print(t[1], id(t[1])) # [20, 30, 99] 1774169087552
元组是可迭代对象,
'''元组的遍历'''
t = ('python', 'world', 98)
'''第一种获取元组元素的方式,使用索引'''
print(t[0])
print(t[1])
print(t[2])
# print(t[3]) 会出行索引越界
'''第二种获取元素的方式,for...in'''
for item in t:
print(item)
python语言提供的内置数据结构
与列表、字典一样都属于可变类型的序列
集合是没有value值的字典
底层数据结构也是通过哈希表计算的
# 集合的创建方式
'''第一种创建方式:使用{}'''
s = {1, 2, 3, 4, 5, 7, 7} # 集合中不允许出现重复的元素,会自动删除重复元素
print(s, type(s)) # {1, 2, 3, 4, 5, 7}
'''第二种创建方式:使用内置函数set()'''
s1 = set({10, 20, 30, 40, 50})
print(s1, type(s1)) # {50, 20, 40, 10, 30}
s2 = set(range(6))
print(s2, type(s2)) # {0, 1, 2, 3, 4, 5}
s3 = set([33, 55, 88, 46, 33]) # 将列表转换成集合
print(s3, type(s3)) # {88, 33, 46, 55}
s4 = set((1, 2, 3, 3, 4, 5, 6, 65)) # 将元组转换为集合
print(s4, type(s4)) # {1, 2, 3, 4, 5, 6, 65}
s5 = set('python') # 将字符串转换成集合
print(s5, type(s5)) # {'p', 'o', 't', 'h', 'y', 'n'}
'''定义空集合'''
# s6 = {} {} 这样只会创建一个空字典
s6 = set()
print(s6, type(s6)) # set()
判断操作:in 或者 not in
新增操作:
add()
update()
删除操作:
remove()
discard()
pop()
clear()
# 集合元素的相关操作
'''集合元素的判断操作'''
s = {10, 20, 30, 405, 60}
print(10 in s) # True
print(100 not in s) # True
'''集合元素的新增操作'''
s.add(80) # 一次添加一个元素
print(s) # {80, 20, 405, 10, 60, 30}
s.update([200, 400, 300]) # 至少添加一个元素,元素类型可以是集合、列表、元组
print(s) # {200, 10, 80, 400, 20, 405, 30, 300, 60}
'''集合元素的删除操作'''
s.remove(200)
print(s) # {10, 80, 400, 20, 405, 30, 300, 60}
# s.remove(500) # remove操作必须要求集合中存在该元素,否则报异常KeyError: 500
s.discard(500) # discard也是删除操作,如果集合中不存在该元素,不会报异常
print(s) # {10, 80, 400, 20, 405, 30, 300, 60}
s.pop() # 没有参数,随机删除一个元素
print(s) # {80, 400, 20, 405, 30, 300, 60}
s.clear() # 清空集合
print(s) # set()
两个集合是否相等
可以使用==或者!=进行判断
一个集合是否是另一个集合的子集
调用issubset经行判断
一个集合是否是另一个集合的超集
调用issuperset函数经行判断
两个集合是否没有交集
调用isdisjoint进行判断
s1 = {10, 20, 30, 40}
s2 = {40, 30, 20, 10}
print(s1 == s2) # True
print(s1 != s2) # False
s3 = {10, 20, 30}
print(s3.issubset(s1)) # s3是s1的子集 True
print(s1.issuperset(s3)) # s1是s3的超集 True
s4 = {10, 200, 300}
print(s1.isdisjoint(s4)) # s1与s3有交集 False 有交集为False,没有交集为True 判断是否没有交集
交集:两个集合取共同部分的数据(集合)
并集:两个集合合并在一起
差集:某一个集合去除跟另一个集合的交集
对称差集:两个集合去除交集
s1 = {10, 20, 30, 40}
s2 = {20, 30, 40, 50, 60}
# 交集操作
print(s1.intersection(s2)) # {40, 20, 30} 取交集
print(s1 & s2) # {40, 20, 30} 等同于intersection 交集
# 并集操作
print(s1.union(s2)) # {40, 10, 50, 20, 60, 30} 取并集
print(s1 | s2) # {40, 10, 50, 20, 60, 30} 等同于union 并集
# 差集操作
print(s1.difference(s2)) # {10} s1不同于s2的数据
print(s1 - s2) # {10}
# 对称差集操作
print(s1.symmetric_difference(s2)) # {50, 10, 60} 减去两个集合的交集
print(s1 ^ s2) # {50, 10, 60}
没有元组的生成式
{i*i for i in range(1,10)}
# 列表生成式
lst = [i*2 for i in range(6)]
print(lst)
# 集合生成式
s = {i*2 for i in range(6)}
print(s)
数据结构 | 是否可变 | 是否重复 | 是否有序 | 定义符号 |
---|---|---|---|---|
列表(list) | 可变 | 可重复 | 有序 | [] |
元组(tuple) | 不可变 | 可重复 | 有序 | () |
字典(dict) | 可变 | key不可重复,value可重复 | 无序 | {key:value} |
集合(set) | 可变 | 不可重复 | 无序 | {} |
创建()或者tuple()
遍历for…in
创建{}或者set{}或者集合生成式
遍历for…in
新增add()或者update()
删除remove()或者descard()或者pop()或者clear()
python中的字符串是基本数据类型,是一个不可变序列
字符串的驻留机制相当于java中的字符串常量池
# 字符串的驻留机制
a = 'python'
b = "python"
c = '''python'''
print(a, id(a)) # python 2233770193072
print(b, id(b)) # python 2233770193072
print(c, id(c)) # python 2233770193072
字符串驻留机制的几种情况(交互模式):
字符串的长度为0或者1时
符合标识符的字符串
字符串只在编译时进行驻留,而非运行时
[-5,256]之间的整数数字
sys中的intern方法强制2个字符串指向同一个对象
PyCharm对字符串进行了优化处理
>>> a ='abc'
>>> b='ab'+'c'
>>> c=''.join(['ab','c'])
>>> a is b
True
>>> a is c
False
>>>
b的值是程序运行之前就已经拼接完毕了
c的值是在程序运行时,通过join方法对字符串进行拼接的
>>> import sys
>>> a='abc%'
>>> b='abc%'
>>> a is b
False
>>> a = sys.intern(b)
>>> a is b
True
>>>
sys中的intern方法强制2个字符串指向同一个对象
之所以使用交互模式演示是因为,PyCharm对字符串进行了优化处理,原本不驻留的PyCharm进行了强制处理
当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串的比较影响性能的。
再需要进行字符串拼接时建议使用,str类型的join方法,而非+,因为join()方法是先计算出所有字符中的长度,然后再拷贝,只new一个对象,效率比“+”效率高。
方法名称 | 作用 |
---|---|
index() | 查找子串第一次出现的位置,如果查找的子串不存在时,则抛出ValueError |
rindex() | 查找子串最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError |
find() | 查找子串第一次出现的位置,如果查找的子串不存在时,则返回-1 |
rfind() | 查找子串最后一次出现的位置,如果查找的子串不存在时,则返回-1 |
s = 'hello,hello'
print(s.index('lo')) # 3
print(s.find('lo')) # 3
print(s.rindex('lo')) # 9
print(s.rfind('lo')) # 9
# print(s.index('k')) # ValueError: substring not found
print(s.find('k')) # -1
方法名称 | 作用 |
---|---|
upper() | 把字符串中所有字符都转成大写字母 |
lower() | 把字符串中所有字符都转成小写字母 |
swapcase() | 把字符串中所有大写字母转成小写字母,所有小写字母转成大写字母 |
capitalize() | 把第一个字符转成大写,把其余字符转成小写 |
title() | 把每一个单词的第一个字母转成大写,每个单词剩余的字母转成小写 |
# 字符串中大小写转换的方法
s = 'hello,python'
a = s.upper() # 转换之后会产生一个新的字符串对象
print(a, id(a)) # HELLO,PYTHON 2406626132592
print(s, id(s)) # hello,python 2406626181232
b = s.lower() # 本来就是小写,全部转换成小写也会产生一个新的字符串对象
print(b, id(b)) # hello,python 1513563026032
print(b is s) # False
s2 = 'HelLo,pyThOn'
c = s2.swapcase() # 大写变小写,小写变大写
print(c) # hELlO,PYtHoN
d = s2.capitalize() # 字符串第一个字符编程大写,其余都变成小写
print(d) # Hello,python
e = s2.title() # 每个单词第一个字母大写,其余小写
print(e) # Hello,Python
对象名称 | 作用 |
---|---|
center() | 居中对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认为空格,如果设置宽度小于实际宽度则返回原字符串 |
ljust() | 左对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认为空格,如果设置宽度小于实际宽度则返回原字符串 |
rjust() | 右对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认为空格,如果设置宽度小于实际宽度则返回原字符串 |
zfill() | 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定宽度小于字符串本身的长度,则返回字符串本身 |
s = 'hello,python'
print(s.center(20, '*')) # ****hello,python****
print(s.ljust(20, '*')) # hello,python********
print(s.ljust(10, '*')) # hello,python 长度不够,默认返回原字符串
print(s.ljust(20)) # hello,python 参数2不写,默认返回空格
print(s.rjust(20, '*')) # ********hello,python
print(s.rjust(20)) # hello,python
print(s.rjust(10)) # hello,python
print(s.zfill(20))# 00000000hello,python 使用0进行填充
print('-8910'.zfill(8))# -0008910 当数字为负数的时候,0会添加到'-'后面
方法名称 | 作用 |
---|---|
split() | 从字符串的左边开始劈分,默认我的劈分字符为空格字符串,返回值为一个列表;通过参数sep指定劈分字符串的劈分符;通过参数maxsplit指定字符串的最大劈分次数,达到最大劈分次数,剩余的字符串单独作为一个整体 |
rsplit() | 从字符串的右边开始劈分,默认我的劈分字符为空格字符串,返回值为一个列表;通过参数sep指定劈分字符串的劈分符;通过参数maxsplit指定字符串的最大劈分次数,达到最大劈分次数,剩余的字符串单独作为一个整体 |
s = 'hello world Python'
lst = s.split() # 不指定分隔符,默认为空格字符串
print(lst) # ['hello', 'world', 'Python']
s1 = 'hello|world|Python'
print(s1.split()) # ['hello|world|Python'] 当没有空格字符串的时候,就不分割
print(s1.split(sep='|')) # ['hello', 'world', 'Python'] sep设置分隔符
print(s1.split(sep='|', maxsplit=1)) # ['hello', 'world|Python'] maxsplit设置最大分割次数
print(s1.rsplit(sep='|', maxsplit=1)) # ['hello|world', 'Python'] maxsplit设置最大分割次数
方法名称 | 作用 |
---|---|
isidentifier() | 判断指定的字符串是否时合法的标识符 |
isspace() | 判断指定的字符串是否全部由空白字符串组成(回车、换行、水平制表符) |
isalpha() | 判断指定的字符串是否全部由字母组成 |
iddecimal() | 判断指定的字符串是否全部由十进制的数字组成 |
isnumeric() | 判断指定的字符串是否全部由数字组成 |
isalnum() | 判断指定的字符串是否全部由字母和数字组成 |
s = 'hello,python'
print(s.isidentifier()) # False 有逗号,不是合法的标识符
print('hello_'.isidentifier()) # True
print('张三_'.isidentifier()) # True
print('\t'.isspace()) # True 是空白字符串
print('abc'.isalpha()) # True
print('张三'.isalpha()) # True
print('张三1'.isalpha()) # Flase
print('123'.isdecimal()) # True
print('123四'.isdecimal()) # False
print('123'.isnumeric()) # True
print('123四'.isnumeric()) # True 罗马数字也可以,也是数字
print('abc1'.isalnum()) # True
print('张三123'.isalnum()) # True
print('abc!'.isalnum()) # False
字符串操作的其他方法
功能 | 方法名称 | 作用 |
---|---|---|
字符串替换 | replace() | 第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换之前的字符串不发生变化,调用该方法时可以通过第三个参数指定最大替换次数 |
字符串的合并 | join() | 将列表或元组中的字符串合并成一个字符串 |
s = 'hello,Python'
print(s.replace('Python', 'java')) # hello,java
s1 = 'hello,python,python,python'
print(s1.replace('python', 'java', 2)) # hello,java,java,python
lst = ['hello', 'java', 'python']
print(','.join(lst)) # hello,java,python
print('*'.join('Python')) # P*y*t*h*o*n
可以使用比较运算符>,>=,<,<=,==,!=
比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,知道两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串的所有后续字符将不再被比较。
print('apple' > 'app') # True
print('apple' > 'banana') # False
print(ord('a'), ord("b")) # 97 98
print(chr(97), chr(98)) # a b
print(ord('周')) # 21608
print(chr(21608)) # 周
字符串时不可变序列,不具备增删改操作,切片操作会产生性的对象。
s = 'hello.python'
s1 = s[:5]
s2 = s[6:]
print(s1) # hello
print(s2) # python
print(s1 + "!" + s2) # hello!python
print('--------------切片[start:stop:step]---------------------------')
print(s[1:5:1]) # ello 左闭右开
print(s[::2]) # hlopto 默认从0开始,默认到字符串最后一个元素,步长表示间隔为2
print(s[::-1]) # nohtyp.olleh 步长为负数,从后往前;步长为正数从前往后
为什么需要格式化字符串
格式化字符串的方式:
%s 表示字符串
%i或%d表示整数
%f表示浮点数
‘我的名字叫%s,今年%d岁了’ %(name,age)
‘我的名字叫{0},今年{1},我真的叫{0}’ format(name,age)
# 第一种占位符%
name = '张三'
age = 21
print('我叫%s,今年%d岁了' % (name, age)) # 我叫张三,今年21岁了
# 第二种占位符
print('我叫{0},今年{1}岁了,我真的叫{0}'.format(name, age)) # 我叫张三,今年21岁了,我真的叫张三
# 第三种方式 f-string
print(f'我叫{name},今年{age}岁了') # 我叫张三,今年21岁了
print('%10d' % 99) # 99 10表示宽度
print('hellohello') # hellohello
print('%f' % 3.1415926) # 3.141593
print('%.3f' % 3.1415926) # 3.142 也用作保留几位小数,表示精度
# 同时表示宽度和精度
print('%10.3f' % 3.1415926) # 3.142
print('{0}'.format(3.1415926)) # 3.1415926
print('{0:.3}'.format(3.1415926)) # 3.14 .3表示总共保留3位数
print('{0:.3f}'.format(3.1415926)) # 3.142 .3f表示的是保留3位小数
print('{0:10.3f}'.format(3.1415926)) # 3.142 10.3f表示的是宽度为10,小数部位保留3位小数
编码:将字符串转换成二进制的数据(bytes)
解码:将二进制数据转换成字符串类型
s = '天涯共此时'
# 编码
print(s.encode(encoding='GBK')) # b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
# 在GBK这种编码格中,一个中文占两个字节
print(s.encode(encoding='UTF-8')) # b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
# 在UTF-8这种编码格中,一个中文占三个字节
# 解码
byte = s.encode(encoding='GBK') # 编码
print(byte.decode(encoding='GBK')) # 解码 天涯共此时
编码跟节码要相同
函数就是执行特定任务和以完成特定功能的一段代码
实现代码复用
隐藏实现细节
提高可维护性
提高可阅读性便于调试
def 函数名 ([输入参数]) :
函数体
[return xxx]
[]表示可有可无
def calc(a, b):
c = a + b
return c
result = calc(10, 20)
print(result) # 30
a,b为形参,10,20为实参
位置传参
关键字传参
def calc(a, b):
c = a + b
return c
# 位置传参
result = calc(10, 20)
print(result) # 30
# 关键字传参
result1 = calc(b=10, a=20)
print(result1) # 30
def fun(arg1, arg2):
print('arg1', arg1)
print('arg2', arg2)
arg1 = 100
arg2.append(10)
print('arg1', arg1)
print('arg2', arg2)
n1 = 11
n2 = [22, 33, 44]
print(n1)
print(n2)
print('-------------------------')
fun(n1, n2)
print(n1)
print(n2)
结果
11
[22, 33, 44]
-------------------------
arg1 11
arg2 [22, 33, 44]
arg1 100
arg2 [22, 33, 44, 10]
11
[22, 33, 44, 10]
在函数的调用过程中,进行参数的传递
如果是不可变对象,在函数体内的修改不会影响实际实参的值
如果是可变对象,在函数体内的修改会影响到实参的值
函数返回多个值时,结果为元组
print(bool(1)) # True
def fun(num):
odd = []
even = []
for i in num:
if i % 2:
odd.append(i)
else:
even.append(i)
return odd, even
print(fun([10, 29, 34, 23, 44, 53, 55])) # ([29, 23, 53, 55], [10, 34, 44]) 返回值为一个元组
函数的返回值
如果函数没有返回值【函数执行完成之后,不需要给调用者返回数据】return可以省略不写
函数的返回值,如果是1个,直接返回原类型
函数的返回值,如果是多个,返回的结果为元组
函数在定义时,是否需要返回值,视情况而定
函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
def fun(a, b=10): # 10为b的默认值
print(a, b)
fun(100) # 100 10 当参数只有一个的时候,b会用默认值
fun(20, 30) # 20 30 当参数有两个的时候,b会使用入参的值
print('hello') # end 默认为\n 换行
print('hello', end='\t')
print('world')
定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
使用✳定义个数可变的位置形参
入参在函数中显示为一个元组
个数可变的位置参数在函数中只能有一个
def fun(*args):
print(args)
print(args[0])
fun(10)
fun(10, 30)
fun(30, 405, 50)
'''
(10,)
10
(10, 30)
10
(30, 405, 50)
30
'''
'''
def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
'''
定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
使用两个✳✳定义个数可变的关键字形参
入参在函数中显示为一个字典
个数可变的关键字参数在函数中只能有一个
def fun1(**args):
print(args)
fun1(a=10) # {'a': 10}
fun1(a=20, b=30, c=40) # {'a': 20, 'b': 30, 'c': 40}
def fun(*args1, **args2):
pass
'''def fun(**args, *args1):
pass
在一个函数定义过程中,既有个数可变的关键字形参,也有个数可变的位置形参时
要求:
个数可变的位置形参必须放在个数可变的关键字形参之前!否则报错
'''
def fun(a, b, c):
print('a=', a)
print('b=', b)
print('c=', c)
# 函数的调用
fun(10, 20, 30) # 函数调用时的位置传参
lst = [11, 22, 33]
fun(*lst) # 在函数调用时,将列表中的每一个元素都转换为位置实参传入
print('-------------------------------------')
fun(a=100, b=200, c=300) # 函数调用时的关键字传参
dic = {'a': 111, 'b': 222, 'c': 333}
fun(**dic) # 在函数调用时,将字典中的每一个元素都转为关键字实参传入 注意,字典中的key必须与函数中的形参名一致
def fun(a, b=10): # b在函数的定义处,所以b是形参,而且进行了赋值,所以b称为默认值形参
print(a)
print(b)
def fun2(*args): # 个数可变的位置形参
print(args)
def fun3(**args): # 关键字可变的关键字形参
print(args)
fun2(10, 20, 30, 40)
fun3(a=11, b=22, c=33, d=44, e=55)
def fun4(a, b, c, d):
print('a', a)
print('b', b)
print('c', c)
print('d', d)
# 调用fun4函数
fun4(10, 20, 30, 40) # 位置实参传递
fun4(a=11, b=22, c=33, d=44) # 关键字实参传递
fun4(11, 22, c=33, d=44) # a,b采用位置实参传递,c,d采用关键字实参传递
'''需求cd只能采用关键字实参传递'''
def fun5(a, b, *, c, d): # 从*之后的参数,在函数调用时,只能采用关键字参数传递
pass
'''函数定义时形参的顺序问题'''
def fun6(a,b,*,c,d,**args):
pass
def fun7(*args,**args1):
pass
def fun8(a,b=10,*args,**args1):
pass
程序代码能访问该变量的区域
根据变量的有效范围可分为:
局部变量:
在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会成为全局变量
全局变量:
函数体外定义的变量,可作用于函数内外
def fun(a, b):
c = a + b # c,就称为局部变量,以为c是在函数体内进行定义的变量,a,b为函数的形参,作用范围也是函数内部,相当于局部变量
print(c)
# print(c)
# print(a) 报错,超出了作用域
name = '周' # nam的作用范围为函数内部和外部都可以使用-->称为全局变量
print(name)
def fun1():
print(name)
fun1()
def fun2():
global age # 函数内定义的变量,使用global声明,该变量变为全局变量
age = 10
print(age)
fun2()
print(age)
一个函数的函数体调用该函数本身,就成为递归函数
递归的组成部分
递归调用与递归终止条件
递归的调用过程
每递归调用一次函数,都会在栈内存分配一个栈帧
每执行完一次函数,才会释放相应的内存空间
递归的优缺点
缺点:占用内存多,效率低
优点:思路和代码简单
# 递归函数
def fun(num):
if num >= 1:
return num * fun(num - 1)
else:
return 1
print(fun(6)) # 720
斐波那契数列:位置上的数等于前两个位置上的数之和
# 斐波那契数列
def fun(n):
if n == 1:
return 1
elif n == 2:
return 1
else:
return fun(n - 1) + fun(n - 2)
print(fun(6)) # 8
print('---------------------------')
# 输出前六位数字
for i in range(1, 7):
print(fun(i))
age = input("请输入年龄:")
print(type(age))
if int(age) >= 18:
print('成年人做事要负法律责任了')
i = 0
while i < 10:
print(i)
i += 1
索引越界IndexError
lst=[11,22,33,44]
print(lst[4]) 索引从0到3越界了
append()方法使用不熟练
lst = []
lst=append('a','b','c') append为list的函数,是.出来的,而且append每次只能添加一个元素
print(lst)
例如求两个数的商,用户可能输入的不是数字或者除数输入的是0
解决方法:利用python提供的异常处理机制,在异常出现时及时捕获,然后内部消化,以达到让程序继续运行的目的
try:
可能出现异常的代码
except 异常类型1:
报错后执行的代码
except 异常类型2:
报错后执行的代码
捕获异常的顺序按照先子类再父类的顺序,为避免遗漏可能出现异常,可以在最后增加最大的异常
最大的异常时BaseException
如果程序try中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块
try:
a = int(input('请输入第一个整数:'))
b = int(input('请输入第二个整数:'))
result = a / b
except BaseException as e:
print('出错了', e) # 出错了 invalid literal for int() with base 10: 'a'
else:
print(type(result)) # float
print('计算结果为:', result) # 5.0
无论是否出异常,finally块中的代码都会被执行,通常用来释放try中申请的资源
try:
a = int(input('请输入第一个整数:'))
b = int(input('请输入第二个整数:'))
result = a / b
except BaseException as e: # try出异常执行此块
print('出错了', e) # 出错了 invalid literal for int() with base 10: 'a'
else: # try不出异常执行此块
print(type(result)) # float
print('计算结果为:', result) # 5.0
finally: # 不论是否出异常,finally块中的代码必定被执行
print('谢谢您的使用!')
序号 | 异常类型 | 描述 |
---|---|---|
1 | ZeroDivisionError | 除(或者取模)零(所有数据类型) |
2 | IndexError | 序列中没有此索引(index) |
3 | KeyError | 映射没有这个键 |
4 | NameError | 未申明/初始化对象(没有属性) |
5 | SyntaxError | Python语法错误 |
6 | ValueError | 传入无效的参数 |
使用traceback模块打印异常信息
import traceback
try:
print('1.---------------------')
num = 1 / 0
except:
traceback.print_exc() # ZeroDivisionError: division by zero
面向过程:线性思维方式去解决问题,第一步干啥,第二步干啥
面向对象:不需要关注过程
Python中的一切皆对象
类的组成
类属性
实例方法
静态方法
类方法
class Student: # 类名由一个或多个单词组成,每个单词的首字母大写,其余小写
native_pace = '吉林' # 直接写在类里面的变量,称为类属性
# 初始化方法
def __init__(self, name, age):
self.name = name # self.name称为实体属性,进行了一次赋值操作,将局部变量name的值赋值给实体属性
self.age = age
# 实例方法 默认由self
def eat(self):
print('学生在吃饭。。。')
# 静态方法
@staticmethod
def method():
print('我使用了staticmethod进行修饰,所以我是静态方法,静态方法当中是不允许写self')
# 类方法
@classmethod
def cm(cls):
print('我是类方法,因为使用了classmethod进行修饰')
'''在类之外定义的称为函数,在类之内定义的称为方法'''
def drink():
print('喝水')
对象的创建称为类的实例化
语法:实例名=类名()
stu1 = Student('张三', 20)
stu1.eat()# 对象名.方法名()
print(stu1.name)
print(stu1.age)
print('------------------------------------')
Student.eat(stu1) # 类名.方法名(类的对象) stu1.eat()的功能相同
Student.method()
类属性:类中方法外的变量称为属性,被该类的所有对象所共享
类方法:使用@classMethod修饰分方法,使用类名直接访问的方法
静态方法:使用@staticMethod修饰的方法,使用类名直接访问的方法
# 类属性的使用方式
print(Student.native_pace) # 吉林
stu1 = Student('张三', 20)
stu2 = Student('李四', 21)
print(stu1.native_pace) # 吉林
print(stu2.native_pace) # 吉林
Student.native_pace = '天津'
print(stu1.native_pace) # 天津
print(stu2.native_pace) # 天津
'''类属性时属于类的,类属性时共享的,类对象通过类指针找到类的类属性'''
# 类方法的使用方式
Student.cm() # 我是类方法,因为使用了classmethod进行修饰
# 静态方法的使用方式
Student.method() # 我使用了staticmethod进行修饰,所以我是静态方法,静态方法当中是不允许写self
python时动态语言,在创建对象之后,可以动态绑定属性和方法
stu1 = Student('张三', 20)
stu2 = Student('李四', 30)
print('-----------为stu2动态绑定性别类型-------------')
stu2.gender = '女' # 动态绑定性别属性
print(stu1.name, stu1.age) # 张三 20
print(stu2.name, stu2.age, stu2.gender) # 李四 30 女 性别属性时stu2特有的属性
print('-----------为stu1动态绑定性别类型-------------')
def show():
print('定义在类之外,称为函数')
stu1.show = show # 动态绑定方法
stu1.show() # 定义在类之外,称为函数
在python中没有专门的修饰符用于属性的私有,如果不希望该属性在类对象外部被访问,前边使用两个”_“修饰
class Student:
def __init__(self, name, age):
self.__age = age # 年龄不希望在类的外部去使用,所以加了两个_
self.name = name
def show(self):
print(self.name, self.__age)
stu = Student('张三', 20)
stu.show()
print(stu.name)# 张三
# print(stu.__age) # AttributeError 属性错误 在类的外部无法访问到
# print(dir(stu))
print(stu._Student__age) # 在类的外部可以通过"_类名__属性名"的方式访问 20
class 子类类名(父类1,父类2,…):
pass
如果一个类没有继承任何类,则默认继承Object类
class Person: # 什么都不写,默认继承object
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person):
def __init__(self, name, age, stu_no):
super().__init__(name, age)
self.stu_no = stu_no
class Teacher(Person):
def __init__(self, name, age, teacherofyear):
super().__init__(name, age)
self.teacherofyear = teacherofyear
stu = Student('张三', 20, '1001')
tea = Teacher('李四', 34, 10)
tea.info()
stu.info()
python支持多继承
class A:
pass
class B:
pass
class C(A, B):
pass
定义子类时,必须在其构造函数中调用父类的构造函数
class Person: # 什么都不写,默认继承object
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person):
def __init__(self, name, age, stu_no):
super().__init__(name, age)
self.stu_no = stu_no
def info(self):
super().info()
print(self.stu_no)
class Teacher(Person):
def __init__(self, name, age, teacherofyear):
super().__init__(name, age)
self.teacherofyear = teacherofyear
def info(self):
super().info()
print('教龄', self.teacherofyear)
stu = Student('张三', 20, '1001')
tea = Teacher('李四', 34, 10)
tea.info()
print('-------------------')
stu.info()
object类是所有类的父类,因此所有类都有object类的属性和方法。
内置的函数dir()可以查看指定对象的所有属性。
Object有一个_str_()方法,用于返回一个对于”对象的描述“,对应于内置函数str()经常用于print()方法,帮助我们查看对象的信息,所以我们经常会对_str()_方法重写。
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '我的名字是{0},今年{1}岁了'.format(self.name, self.age)
stu = Student('张三', 20)
print(dir(stu))
print(stu) # 默认会调用_str()_方法
print(type(stu))
多态就是具有多种形态,指的是:即便不知道一个变量所引用的对象到底是什么类型,任然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。
静态语言和动态语言关于多态的区别
静态语言实现多态的三个必要条件:(java多态必须有这三个要素)
继承
方法重写
父类型的引用指向子类型的对象
动态语言的多态崇尚”鸭子类型“,当看到一只鸟走起来像鸭子、游泳像鸭子、走起来也像鸭子,那么这只鸟就可以被称为鸭子,在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。(python多态只关心是否有这个方法)
# 开发人员: 周 伟
# 开发时间: 2021/11/24 9:21
class Animal(object):
def eat(self):
print('动物会吃')
class Dog(Animal):
def eat(self):
print('狗吃骨头')
class Cat(Animal):
def eat(self):
print('猫吃鱼')
class Person:
def eat(self):
print('人吃五谷杂粮')
# 定义函数
def fun(obj):
obj.eat()
# 调用函数
fun(Cat())
fun(Dog())
fun(Animal())
print('------------------')
fun(Person())
特殊属性: __dict__ 获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法:
__len__()通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
__add__()通过重写__add__()方法,可以使自定义对象具有“+”功能
__new__()用于创建对象
__init__()对创建的对象进行初始化
class A:
pass
class B:
pass
class C(A, B):
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print('吃')
# 创建C类的对象
x = C('Jack', 20)
print(x.__dict__) # 实例对象,可以获取实例对象的属性 {'name': 'Jack', 'age': 20}
print(
C.__dict__) # 类对象,可以获取类对象有哪些方法{'__module__': '__main__', '__init__': , 'eat': , '__doc__': None}
print('----------------')
print(x.__class__) # 输出了对象所属的类
print(C.__bases__) # (, ) 输出了类的父类型元组
print(C.__base__) # 输出第一个父类型,按父类型写的顺序排的,谁写在前面输出谁
print(C.__mro__) # (, , , ) 显示所有继承的类,查看类的继承结构
print(A.__subclasses__()) # [] 查看有哪些子类列表
add和len方法是使用:
class Student:
def __init__(self, name):
self.name = name
def __add__(self, other):
return self.name + other.name
def __len__(self):
return len(self.name)
stu1 = Student('张三')
stu2 = Student('李四')
s = stu1 + stu2 # 张三李四 实现了两个对象的加法运算(因为在Student中编写了__add__()特殊方法)
print(s)
print('------------------------')
lst = [11, 22, 33, 44]
print(len(lst)) # len是内置函数len 4
print(lst.__len__()) # 4
print(len(stu1)) # 2
new和init方法的作用
class Person(object):
def __new__(cls, *args, **kwargs):
print('__new__被调用执行了,cls的id值为{0}'.format(id(cls)))
obj = super().__new__(cls)
print('创建的对象的id为:{0}'.format(id(obj)))
return obj
def __init__(self, name, age):
print('__init__方法被调用了,self的id为{0}'.format(id(self)))
self.name = name
self.age = age
print('object这个类对象的id为:{0}'.format(id(object)))
print('Person这个类对象的id为:{0}'.format(id(Person)))
# 床架Person类的实例对象
p1 = Person('张三', 20)
print('p1这个Person类的实例对象的id:{0}'.format(id(p1)))
object这个类对象的id为:140724580961792
Person这个类对象的id为:1638837642336
__new__被调用执行了,cls的id值为1638837642336
创建的对象的id为:1638839062288
__init__方法被调用了,self的id为1638839062288
p1这个Person类的实例对象的id:1638839062288
变量的赋值操作:只是形成两个变量,实际上还是指向同一个对象
浅拷贝:python拷贝一般都是浅拷贝,拷贝是,对象包含的子对象内容不拷贝,
因此,原对象与拷贝对象引用同一个子对象
深拷贝:使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,原对象和拷贝对象的子对象也不相同
class Cpu:
pass
class Disk:
pass
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
# 变量的赋值
cpu1 = Cpu()
cpu2 = cpu1
print(cpu1, id(cpu1)) # <__main__.Cpu object at 0x0000014B5D957FD0> 3036854452176
print(cpu2, id(cpu2)) # <__main__.Cpu object at 0x0000014B5D957FD0> 3036854452176
# cpu1跟cpu2指向同一个对象
print('-------------------')
# 类的浅拷贝
disk = Disk()
computer = Computer(cpu1, disk) # 创建一个计算机类的对象
import copy
computer2 = copy.copy(computer)
print(computer, computer.cpu, computer.disk)
print(computer2, computer2.cpu, computer2.disk)
# 此时两个computer的对象是不同的,但是其属性cpu跟disk确实指向同一个内存地址,是相同的,这就是浅拷贝
print('-----------------------')
computer3 = copy.deepcopy(computer)
print(computer, computer.cpu, computer.disk)
print(computer3, computer3.cpu, computer3.disk)
# 此时两个conputer的对象是不相同的,cpu跟disk两个属性也完成了拷贝
<__main__.Cpu object at 0x000001D432C08FD0> 2010896175056
<__main__.Cpu object at 0x000001D432C08FD0> 2010896175056
-------------------
<__main__.Computer object at 0x000001D432C08E50> <__main__.Cpu object at 0x000001D432C08FD0> <__main__.Disk object at 0x000001D432C08F70>
<__main__.Computer object at 0x000001D432C08D60> <__main__.Cpu object at 0x000001D432C08FD0> <__main__.Disk object at 0x000001D432C08F70>
-----------------------
<__main__.Computer object at 0x000001D432C08E50> <__main__.Cpu object at 0x000001D432C08FD0> <__main__.Disk object at 0x000001D432C08F70>
<__main__.Computer object at 0x000001D432C08790> <__main__.Cpu object at 0x000001D432C08430> <__main__.Disk object at 0x000001D432C08460>
模块英文为modules
函数与模块的关系
一个模块中可以包含多个函数
python中以一个扩展名为.py的文件就是一个模块
使用模块的好处:
方便其他程序和脚本的导入并使用
避免函数名和变量名的冲突
提高代码的可维护性
提高代码的可重复性
新建一个.py文件,名称尽量不要与python自带的标准模块名称相同,要见名知意
import 模块名称 [as 别名]
import math # 关于数学运算
print(id(math))
print(type(math))
print(math)
print(math.pi) # 3.141592653589793
print('-----------------')
print(dir(math))
print(math.pow(2, 3)) # 8.0 2的3次方
print(math.ceil(9.001)) # 10 向上取整
print(math.floor(9.999)) # 9 向下取整
from 模块名称 import 函数/变量/类
from math import pi # 单独导入某个模块中的特定的函数/变量/类
print(pi) # 3.141592653589793
在每个模块的定义中都包括一个记录模块名的变量__name__,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其他模块中执行,那么他可能在解释器的顶级模块中执行,顶级模块的__name__变量的值为__main__
if __name__ == '__main__':
pass
意思是直接运行当前.py文件本身的时候,才会执行pass,而当作为模块引入到变得.py文件,运行别的.py文件时,pass中的代码不会执行
如果不适用if判断,则会导致pass中的程序,在别的.py文件执行的过程中也会执行
包时一个分层次的结构,它将一组功能相近的模块组织在一个目录下
作用:
代码规范
避免模块冲突
包与目录的区别
包含__init__.py文件的目录成为包
目录通常不包含__init__.py文件
包的导入
import 包名.模块名
import package
import calc
# 使用import方式进行导入时,只能跟包名或者模块名
from package import module_A
from package.module_A import a
# 使用from...import可以导入包,模块,函数,变量
模块名 | 描述 |
---|---|
sys | 与python解释器及其环境操作相关的标准库 |
time | 提供与时间相关的各种函数的标准库 |
os | 提供了访问操作系统服务功能的标准库 |
calendar | 提供了与日期相关的各种函数的标准库 |
urllib | 用于读取来自网上(服务器)数据的标准库 |
json | 用于使用JSON序列化和反序列化对象 |
re | 用于在字符串中执行正则表达式匹配和替换 |
math | 提供标准算数运算函数的标准库 |
decimal | 用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算 |
logging | 提供了灵活的记录事件、错误、警告和调试信息等日志信息的功能 |
import sys
import time
import os # 操作系统服务功能的标准库 文件存储啥的
import calendar # 获取日期
import urllib.request # 爬虫需要使用到
import json # 序列化和反序列化 爬虫也会用到
import re # 正则表达式 爬虫也会用到
import math
import decimal # 浮点数进行运算的时候会出行不准确的情况
import logging # 日志功能
print(sys.getsizeof(24)) # 28
print(sys.getsizeof(45)) # 28
print(sys.getsizeof(True)) # 28
print(sys.getsizeof(False)) # 24
print(time.time()) # 1637746651.9063413
print(time.localtime(
time.time())) # time.struct_time(tm_year=2021, tm_mon=11, tm_mday=24, tm_hour=17, tm_min=37, tm_sec=31, tm_wday=2, tm_yday=328, tm_isdst=0)
print(urllib.request.urlopen('http://www.baidu.com').read()) # 将百度这个地址中所有数据读取回来
print(math.pi) # 3.141592653589793
第三方模块在线安装方式: pip install 模块名 在doc命令中使用
第三方模块使用:import 模块名
import schedule
import time
def job():
print('哈哈')
schedule.every(3).seconds.do(job)# 设置定时任务规则
while True:
schedule.run_pending()# 启动定时任务
time.sleep(1)
python的解释器使用的shiunicode(没存)
.py文件在磁盘上使用UTF-8存储(外存)
utf-8相当于unicode的具体实现
设置编码格式:在模块第一行添加# encoding=gbk
# encoding=gbk
print('你好中国')
不同的编码格式会导致文件大小不一样
文件的读写俗称“IO操作”input,output
文件独写操作流程
python操作文件–>打开或者新建文件–>读、写文件–>关闭资源
读是指从别的地方读入内存当中
写是指从内存中写道磁盘当中
读入写出
file = open(filename [,mode,encoding])
解释:
file 表示被创建的文件对象
open 创建文件对象的函数
filename 要创建或者打开的文件的名称
mode 打开模式默认为只读
encoding 默认文本文件中字符的编写格式为gbk
读取磁盘文件的内容
file = open('a.txt', 'r')
print(file.readlines())
file.close()
按文件中数据的组织形式,文件分为以下两大类
文本文件:存储的普通“字符”文本,默认为unicode字符集,可以使用记事本程序打开
二进制文件:把数据内容用“字节”进行存储,无法用记事本打开,必须使用专用的软件文件打开,举例:MP3音频文件,jpg图片文件,doc文档等
打开模式 | 描述 |
---|---|
r | 以只读模式打开,文件的指针将会放在文件的开头 |
w | 以只写模式打开,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头 |
a | 以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头,如果文件存在,则在文件末尾追加内容,文件指针在原文件末尾 |
b | 以二进制方式打开文件,不能单独使用,需要与其他模式一起使用,rb或者wb |
+ | 以独写方式打开文件,不能单独使用,需要与其他模式一起使用,a+ |
file = open('a.txt', 'r')
print(file.readlines())
file.close()
file = open('b.txt', 'w')
file.write('Python')
file.close()
file = open('b.txt', 'a')
file.write('Python')
file.close()
src_file = open('copy.gif', 'rb')
target_file = open('copylogo.gif', 'wb')
target_file.write(src_file.read())
src_file.close()
target_file.close()
方法名 | 说明 |
---|---|
read([size]) | 从文件中读取size个字节或字符的内容返回。若省略[size]则读取到文件末尾,即一次读取文件所有的内容 |
readline() | 从文本文件中读取一行内容 |
readlines() | 把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回 |
write(str) | 将字符串str内容写入文件 |
writelines(s_list) | 将字符串列表s_list写入文本文件,不添加换行符 |
seek(offset[,whence]) | 把文件指针移动到新的位置,offset便是相对于whence的位置: offset:为正往结束方向移动,为负往开始方向移动 whence:不同的值代表不同的含义 0:表示从文件头开始计算 1:表示从当前位置开始计算 2:表示从文件尾开始计算 |
tell() | 返回文件指针的当前位置 |
flush() | 把缓冲区的内容写入文件,但不关闭文件 |
close() | 把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源 |
file = open('a.txt', 'r')
print(file.read())# 中国
# 美丽
print(file.readline())# 中国
print(file.readlines())# ['中国\n', '美丽']
file.close()
file = open('c.txt', 'a')
# print(file.read())# 中国
# # 美丽
# print(file.readline())# 中国
# print(file.readlines())# ['中国\n', '美丽']
# file.write('hello')# hello
lst = ['java', 'go', 'python']
file.writelines(lst) # hellojavagopython
file.close()
file = open('c.txt', 'r') # hellojavagopython
file.seek(2) # 中文占两个字节 文件指针往后移动两位
print(file.read()) # llojavagopython
print(file.tell()) # 17 获取文件指针的位置
file.close()
with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭,以此来达到释放资源的目的
with open('a.txt','rb') as src_file :
with语句体
with open('a.txt', 'r') as file:
print(file.read())
print(type(open('a.txt', 'r'))) #
'''
MvContentMgr类实现了特殊方法__enter__(),__exit__()称该类对象遵守了上下文管理器协议
该类对象的实例对象,称为上下文管理器
'''
class MvContentMgr:
def __enter__(self):
print('enter方法被调用执行了')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit方法被调用执行了')
def show(self):
print('show方法被调用执行了')
with MvContentMgr() as file: # 相当于file=MvContentMgr()
file.show() # 不论是否发生异常,只要跳出with块,就会执行__exit__()方法
# enter方法被调用执行了
# show方法被调用执行了
# exit方法被调用执行了
os模块是python内置的与操作系统功能和文件相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样。
os模块与os.path模块用于对目录或文件进行操作
# os模块与操作系统相关的模块,可以调用系统文件
import os
# 调用操作系统的功能
os.system('notepad.exe') # 打开记事本
os.system('calc.exe')# 打开计算机
# 直接调用可执行文件
os.startfile('C:\\Program Files\\HeidiSQL\\heidisql.exe')
函数 | 说明 |
---|---|
getcwd() | 返回当前的工作目录路径 |
listdir(path) | 返回指定路径下的文件和目录信息 |
mkdir(path[,mode]) | 创建目录 |
makedirs(path1/path2…[,mode]) | 创建多级目录 |
rmdir(path) | 删除目录 |
removedirs(path1/path2…) | 删除多级目录 |
chdir(path) | 将path设置为当前工作目录 |
import os
print(os.getcwd())
print(os.listdir('..\\chap15'))
os.mkdir('newdir2')# 创建目录
os.makedirs('A/B/C') # 创建多级目录 A目录下有B目录,B目录下有C目录
os.rmdir('newdir2') # 删除目录
os.removedirs('A/B/C') # 移除多级目录
os.chdir('../') # 将上一级目录设置问工作目录
函数 | 说明 |
---|---|
abspath(path) | 用于获取文件或者目录的绝对路径 |
exists(path) | 用于判断文件或者目录是否存在,如果存在返回True,不存在返回False |
join(path,name) | 将目录与文件名拼接起来 |
splitext() | 分离文件名与扩展名 |
basename(path) | 从一个目录中提取文件名 |
dirname(path) | 从一个路径中提取文件路径,不包括文件名(文件所在目录的路径) |
isdir(path) | 用于判断是否为路径 |
import os.path
print(os.path.abspath('demo13.py')) # 获取文件或目录的绝对路径
print(os.path.exists('demo17.py'), os.path.exists('demo18.py')) # True False
print(os.path.join('E:\\python', 'demo12.py')) # E:\python\demo12.py 拼接起来
print(os.path.split('E:\\python\\chap15\\demo17.py')) # ('E:\\python\\chap15', 'demo17.py') 拆分最后一个文件
print(os.path.splitext('demo17.py')) # ('demo17', '.py') 拆分文件与后缀名
print(os.path.basename('E:\\python\\chap15\\demo17.py')) # demo17.py 提取一个路径中的文件名(含后缀)
print(os.path.dirname('E:\\python\\chap15\\demo17.py')) # E:\python\chap15 提取文件或者目录所在的路径
print(os.path.isdir('E:\\python\\chap15\\demo17.py')) # False 不是目录,因为结尾是文件
# 列出指定目录下所有的以.py结尾文件
import os
lst = os.listdir() # 当前工作目录下的目录和文件信息
lst1 = []
for file in lst:
if file.endswith('.py'):
lst1.append(file)
# str = os.path.splitext(file)[1]
# if str == '.py':
# lst1.append(file)
print(lst1)
遍历某个文件夹下所有的子目录和文件,以及子目录下的内容
import os
path = os.getcwd()
lst_file = os.walk(path)
print(lst_file)
for dirpath, dirname, filename in lst_file:
'''print(dirpath) # 当前的路径 列表
print(dirname) # 当前目录下有哪些目录 列表
print(filename) # 当前目录下有哪些文件 列表
print('------------------------')'''
for dir in dirname:
print(os.path.join(dirpath,dir))
for file in filename:
print(os.path.join(dirpath,file))
print('--------------------------------------------')
添加学生信息及成绩信息
将学生信息保存到文件中
修改和删除学生信息
查询学生信息
根据学生成绩进行排序
统计学生的总分
录入、查找、删除、修改学生信息
学生成绩排名
总人数统计
显示全部学生信息
类似于jdk8新特性中的表达式
d = dict(eval(字符串))
安装第三方模块
在线安装
pip install PyInstaller
执行打包操作
pyinstaller -F 文件的绝对路径
-F的意思是只生成一个扩展名为exe的可执行文件
变量名等,两个单词之间_连接,例如book_name
zip使用
list1=[]
list2=[]
for s,a in zip(list1,list2):
print(s.a)
pycharm的功能设置输出内容的颜色
\033[显示方式;字体颜色;背景颜色m
print(‘\003[0;35m你好吗’) # 你好吗
def fun():
num = 4
print(num, '的二进制数为', bin(num))
print(str(num) + '的二进制数为' + str(bin(num)))
print('%s的二进制数为%s' % (num, bin(num)))
print('{0}的二进制数为{1}'.format(num, bin(num)))
print(f'{num}的二进制数为{bin(num)}')
print(f'{num}的八进制数为{oct(num)}')
print(f'{num}的十六进制数为{hex(num)}')
if __name__ == '__main__':
while True:
try:
fun()
break
except:
print('只能输入整数!!!')
判断字符串是否都是数字str.isdigit()