ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python基础版笔记

2022-08-01 23:34:51  阅读:167  来源: 互联网

标签:__ 10 输出 python 基础 笔记 lst print


python教程

应用场景:数据处理、网络应用的后端编写、自动化脚本

基础学习:1.python能做什么;2.变量算法解释器、基本数据类型、列表元组字符串字典操作方法;3.条件,循环和相关执行语句(if else elif while for continue bresk 列表推导式 异常处理);4.面向对象OOP,程序结构

、代码重用避免代码冗余打包代码

快捷键:

Alt+Enter 快速修复当前代码,没有import进模块,自动导入模块

ctrl+X 删除整行代码

Ctrl+Alt+L PEP8的代码标准将当前代码格式化

1.输出函数print

# print可以输出数字、字符串、数字表达式;(输出在控制台上)
print(3.14)
print(56)
print('人生苦短,我用python')
print(3+4)
# print将文件输出到文件中;
# 运行几次就输出几次
fe = open('E:/(network)/python资料及练习/test.txt','a+') # a+表示如果文件不存在就创建,存在就在文件内容后面追加
print('hello world!',file = fe)
fe.close()
# print输出内容在一行当中,用逗号,输出以空格相隔
print('hello','world','python')

输出结果:3.14
56
人生苦短,我用python
7

​ hello world python

注意:print函数的括号里有判断的话返回值为布尔值!

2.转义字符与元字符

# 转义字符:\ 加转义功能的首字母
print('hello\nworld')    # 换行--newline
print('hello\tworld')    # tab,一个tab键四个空格
print('helloooo\tworld')
print('hello\rworld')    # 回车,world将hello覆盖
print('hello\bworld')    # 退一格

print('http:\\\\www.baidu.com')
print('她说:’我要学习python‘')  #python3支持中文,python2的话这样写:print('她说:’我要学习python‘')

# 元字符,不希望字符串中的转义字符起作用,就使用元字符,在字符串之前加上r,或R
print(r'hello\nworld')
print(r'hello\nworld') # 注意末尾不能加反斜杠\:print(r'hello\nworld\')

输出结果:

​ hello
​ world
​ hello world
​ helloooo world
​ world
​ hellworld
​ http:\www.baidu.com
​ 她说:’我要学习python‘
​ hello\nworld
​ hello\nworld

3.字符编码与4.标识符与保留字

# 字符编码:GBK   unicode--utf-8
print(chr(0b100111001011000))
print(ord('乘'))
# 标识符和保留字
import keyword
print(keyword.kwlist)   #输出的就为保留字
# 标识符规则:不能以数字、保留字开头,区分大小写;变量、函数、类、模块和其它对象起的名字为标识符

输出结果:


20056
['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']

5.变量的定义与使用

# 变量:内存中一个带标签的盒子;name(变量名)=(赋值运算符)马丽荣(值)
# 变量由三部分组成:ID,type,value;
name = "马丽荣"
print(name)
print('标识:',id(name))
print('类型:',type(name))
print('值:',name)

输出结果:

马丽荣
标识: 2080713636240
类型: <class 'str'>
值: 马丽荣

6.变量的多次赋值

当变量多次赋值之后,变量名会指向新的空间;

name = '马丽亚'
name = '出溜冰'
print(name)

输出结果:出溜冰

name = '马丽亚'
print(name)
name = '出溜冰'
print(name)

输出结果:

马丽亚
出溜冰

7.数据类型

7.1整形 int
# 可以表示为正数、负数、零;
n1 = 90
n2 = -76
n3 = 0
print(n1,type(n1))
print(n2,type(n2))
print(n3,type(n3))

输出结果:

90 <class 'int'>
-76 <class 'int'>
0 <class 'int'>

# 可以表示为二进制、八进制、十六进制,默认为十进制
print('十进制',118)   # 范围0-9
print('八进制',0o176)  # 范围0-7 以0o开头
print('十六进制',0x0AF6)    # 范围0-9 A-F 以0x开头
print('二进制',0b11111111)    # 范围0-1,以0b开头

输出结果:

十进制 118
八进制 126
十六进制 2806
二进制 255

7.2浮点型 float
a = 3.14159
print(a,type(a))
# 使用浮点数进行计算,可能会出现位数不确定的情况
n = 1.1
n1 = 2.2
n2 = 3.3
print(n+n1)
from decimal import Decimal
print(Decimal('1.1')+Decimal('2.2'))

输出结果:

3.14159 <class 'float'>
3.3000000000000003
3.3

7.3布尔类型 bool (True,Flase)
# 表示真或假的值
f1 = True
f2 = False
print(f1,type(f1))
print(f2,type(f2))
print(f1+1) # 1+1=2,f1为真表示1
print(f2+1) # 0+1=1,f2为假表示0

输出结果:

True <class 'bool'>
False <class 'bool'>
2
1

7.4字符串 str
# 称为不可变的字符序列
str = '人生苦短,我用python'   #单引号与双引号都可表示一行的字符串
str1 = "人生苦短,我用python"  
str2 = '''
人生苦短,我用python1
人生苦短,我用python2
人生苦短,我用python3
'''                     # 三引号定义的字符串可以分布在连续的多行
print(str,type(str))
print(str1,type(str1))
print(str2,type(str2))

输出结果:

人生苦短,我用python <class 'str'>
人生苦短,我用python <class 'str'>

人生苦短,我用python1
人生苦短,我用python2
人生苦短,我用python3
<class 'str'>

8.数据类型转化

8.1 为什么进行数据转换
# 数据类型转化,将不同的数据类型的数据拼接在一起;
name = '张三'
age = 20
print(type(name),type(age)) # 数据类型不同
# print('我叫'+name+'今年,'+age+'岁')  # 报错,类型转化
print('我叫'+name+',今年'+str(age)+'岁') # 加号为连接符

输出结果:

<class 'str'> <class 'int'>
我叫张三,今年20岁

8.2 str()函数将其他类型转化成str类型
print('--------------str()函数将其他类型转化成str类型----------')
a = 10
b = 198.9
c = False
print(type(a),type(b),type(c))
print(type(str(a)),type(str(b)),type(str(c)))

输出结果:

--------------str()函数将其他类型转化成str类型----------
<class 'int'> <class 'float'> <class 'bool'>
<class 'str'> <class 'str'> <class 'str'>

8.3 int()函数将其他类型转化为int类型
print('-----------int()函数将其他类型转化为int类型--------')
# 文字类与小数类的字符串不能转化为int;浮点数转化为int,末尾为0
s1 = '128'
f1 = 1.595
s2 = '77.889'
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)))    # 将float转成int类型,截取整数
# print(int(s2),type(int(s2)))  # 报错,字符串内为小数串
print(int(ff),type(int(ff)))
# print(int(s3),type(int(s3)))  # 字符串内为字母,不能转为int

输出结果:

-----------int()函数将其他类型转化为int类型--------
<class 'str'> <class 'float'> <class 'str'> <class 'bool'> <class 'str'>
128 <class 'int'>
1 <class 'int'>
1 <class 'int'>

8.4 float()函数将其他类型转化为float型
print('-----------float()函数将其他类型转化为float型------------')
#文字类无法转化为浮点型;整数转成浮点数,末尾为.0
ss1 = 128
ff1 = 1.595
ss2 = '77.889'
fff = False
ss3 = 'hello'
print(type(ss1),type(ff1),type(ss2),type(fff),type(ss3))
print(float(ss1),type(float(ss1)))
print(float(ff1),type(float(ff1)))
print(float(ss2),type(float(ss2)))
print(float(fff),type(float(fff)))
# print(float(ss3),type(float(ss3)))

输出结果:

-----------float()函数将其他类型转化为float型------------
<class 'int'> <class 'float'> <class 'str'> <class 'bool'> <class 'str'>
128.0 <class 'float'>
1.595 <class 'float'>
77.889 <class 'float'>
0.0 <class 'float'>

python中的注释:中文编码注释-->在文件开头加上中文声明注释,用以指定源码文件的编码格式!

#coding:utf-8 或者 gbk

9.输入函数input()

介绍:接收来自用户的输入;返回类型为str;对输入的值进行存储;

present = input('大圣想要神魔礼物:')
print(present,type(present))

输出结果:

大圣想要神魔礼物:金箍棒
金箍棒 <class 'str'>

# 练习:输入两个整数,并对其求和;
nu1 = int(input('输入第一2个数:'))
nu2 = int(input('输入第二个数:'))
sum = nu1+nu2
print(sum)

输出结果:

输入第一个数:2
输入第二个数:2
4

10.运算符

10.1 算数运算符
标准算数运算符:

加(+)、减(-)、乘(*)、除(/)、整除(//)

取余运算符:%

幂运算符:**

print(1+1)  # 加法运算
print(2-1)  # 减法运算
print(2*4)  # 乘法运算
print(11/2)  # 除法运算
print(6%4)  # 取余运算:6除4取余数
print(9//8)  # 整除运算:9除8取整商
print(2**3)    #幂运算:2的3次方
输出结果:
2
1
8
5.5
2
1
8

算数运算符:

运算符 表示 例子 结果
9%4 1
% 取余一正一负 9%-4 9-(-4)*(-3)=-3
余数=被除数-除数*商 -9%4 -9-4*(-3)=3
-9%-4 -1
// 整除(一正一负向下取整) 9//-4 -3(2.25=2+1)
9//4 2
-9//4 -3
-9//-4 2
print(12%8)   #4
print(12%-8)    # 12-(-8)*(-2)=-4
print(-12%8)    # -12-8*(-2)=4
print(-12%-8)   # -4
# 输出结果为
4
-4
4
-4
赋值运算符

执行顺序为从右-->左;

支持链式赋值;a=b=c=20

支持参数赋值;+=、-=、*=、//=、%=

a = 10
a += 12	# a=a+12,a=10
print(a)
# 输出结果为:22

支持系列解包赋值;a,b,c,=20,30,40

# 交换两个变量的值
a,b=10,20
print('交换之前:a,b',(a,b))
a,b=b,a
print('交换之后:a,b',(a,b))

输出结果:

交换之前:a,b (10, 20)
交换之后:a,b (20, 10)

比较运算符

对变量或表达式的结果进行大小、真假等比较;

# 运算符:>,<,>=,<=,!=
# == 对象vlaue的比较,
# is,is not 对象的id比较

”==“比较的是值,而“=”是赋值;比较对象的标识使用的是“is”或“is not”

a=10
b=10
print(a==b) # 返回为True,说明a与b的vlaue相等
print(a is b)   # 返回为True,说明a与b的标识相等
print(a,id(a))

输出结果:

True
True
10 2242092362320

lis1 = [11,22,33,44]
lis2 = [11,22,33,44]
print(lis1==lis2)
print(lis1 is lis2) # id不同
print(lis1,id(lis1))
print(lis2,id(lis2))
print(lis1 is not lis2)
# 输出结果:
True
False
[11, 22, 33, 44] 2212795138368
[11, 22, 33, 44] 2212795125696
True

比较运算符的结果为布尔类型

a,b = 10,20
print('a>b?',a>b)

输出结果:

a>b? False

布尔运算符

对于布尔值之间的运算;

都有and、or、not in、in;

and:一假则假

a,b = 1,2
print(a==1 and b==2)  # True and True 为True
print(a==1 and b<1)     # True and Flase 为Flase
print(a!=1 and b==2)    # Flase and True 为Flase
print(a!=1 and b<1)     # Flase and Flase 为Flase

or:一真则真

print(a==1 or b==2)  # True and True 为True
print(a==1 or b<1)     # True and Flase 为True
print(a!=1 or b==2)    # Flase and True 为FTrue
print(a!=1 or b<1)     # Flase and Flase 为Flase

in与not in

f = True
ff = False
print(not f)    #对布尔类型操作数进行取反-----Flase

s = 'helloworld'
print('w' in s)	# True
print('k' not in s)	# True
位运算符

将数据转成二进制计算;

1.位与&:对应位数都是1,结果位数才是1,否则为零

print(4&8)     # 按位与&,同为1时结果为1(两个十进制转化为二进制按位计算)
输出结果:0
0000 0100
0000 1000

2.位或|:对应位数都是0,结果位数才是0,否则为1

print(4|8)      #按位或|,同为0时结果为0
输出结果:12
0000 0100
0000 1000
0000 1100

3.左移位<<:高位溢出,低位补零(乘以2)

print(4<<1)     # 向左移动1位(4乘以2)
输出结果:8

4.右移位>>:高位补零,低位丢弃(移一位除以2---2的幂)

print(4>>2)     # 向右移动2位(4除以2**2)
输出结果为:1

补:二进制原码+1=补码

运算符的优先级

算数运算符>位运算>比较运算符>布尔运算>赋值运算;

有括号会先计算括号里的

11.流程控制

11.1程序的组织结构
11.1.1顺序结构

程序从上到下顺序地执行代码,中间没有任何的判断和跳转,直到程序结束;

对象的布尔值:在python中一切皆对象,所有对象都有一个布尔值,获取对象的布尔值,使用内置函数bool();

print(bool(False))
print(bool(0))
print(bool(0.0))
print(bool(''))
print(bool(None))
print(bool(""))
print(bool([]))
print(bool(list()))
print(bool(()))
print(bool(tuple()))
print(bool({}))
print(bool(dict()))
print(bool(set()))
print('--以上的对象布尔值为False,其余都为True--')

print(bool(18))
print(bool("hello world"))

False、数值0、None、空字符串、空列表、空元组、空字典、空集合的布尔值为False;

11.1.2选择结构(if 语句)

程序根据判断条件的布尔值选择性的执行部分代码,明确的让计算机知道在神魔的条件下,该去做什么;

单分支结构:如果...就

money = 1000
je = int(input('取款金额:'))
if je<=money:  # if 条件表达式:(条件表达式为布尔值)
    money = money-je
    print('取款成功,余额为:',money)
 
# 输出结果:
取款金额:920
取款成功,余额为: 80

双分支结构:如果不满足...就

语法结构:

if 条件表达式:

​ 条件执行体1

else:

​ 条件执行体2

zs = int(input('输出一个整数:'))
if zs%2==0:
    print('此数为偶数!')
else:
    print('此数为奇数!')

# 键盘中输入一个数,判断是否为奇数还是偶数;
输出结果:
输出一个整数:100
此数为偶数!

多分支结构:...是...? 是或不是

if 条件表达式1:
	条件执行体1
elif 条件表达式2:
	条件执行体2
elif 条件表达式N:
	条件执行体N
[else:]			# 可写可不写
    条件执行体N+1	
# 从键盘中录入一个“整数”成绩,判断它的范围
# 90-100:A  80-90:B   70-80:C 60-70:及格  60以下不及格
score = int(input('请输入一个整数成绩:'))
if score>=90 and score<=100:# 可以写成90<=score<=100
    print('A')
elif score>=80 and score<90:
    print('B')
elif score>=70 and score<80:
    print('良好')
elif score>=60 and score<70:
    print('合格')
elif score<60 and score>=0:
    print('不及格')
else:
    print('对不起,输入的成绩不在范围之内!')
    
输出结果:
请输入一个整数成绩:88
B

嵌套if

语法结构:
if 条件表达式1:
	if 内层条件表达式:
		内层条件执行体1
	else:
		内层条件执行体2
else:
	条件执行体
'''
会员  >=200  8折
     >=100  9折
     不打折
非会员  >=200 9.5折
        不打折
'''
huiyuan = input('是否为会员y/n:')
money = float(input('请输入钱:'))
if huiyuan=='y':     # 判断为会员
   if money>=200:
      print('会员最后金额为:',money*0.8)
   elif money>=100:
      print('会员最后金额为:',money*0.9)
   else:
       print('会员最后金额为:',money)
else:   # 判断不会为会员
    if money>=200:  # 大于等于号前后注意空格,空格也有影响;
        print('最后非会员金额为:',money*0.95)
    else:
        print('最后非会员金额为:',money)
        
# 输出结果:
是否为会员y/n:n
请输入钱:1000
最后非会员金额为: 950.0

从键盘中输入两个数,比较两个数的大小(两种表达方法):

num = float(input('输入第一个数:'))
numm = float(input('输入第二个数:'))

if num>=numm:
    print(num,'大于等于',numm)
else:
    print(num,'小余等于',numm)

条件表达式

num = float(input('输入第一个数:'))
numm = float(input('输入第二个数:'))
print((str(num)+'大于等于'+str(numm))  if num>=numm else  (str(num)+'小余等于'+str(numm)))
# 如果if后的条件为True就执行前面的语句,为Flase就执行后面的语句;

条件表达式:是if....else的简写
语法结构:x if 判断条件  else  y
运算规则:如果判断条件的布尔值为True,条件表达式的返回值为x,否则条件表达式的返回值为Flase;

pass语句

是:语句什么都不做,只是一个占位符,用在语法上需要语句的地方;

什么时候用:先搭建语法结构,还没想好代码怎么写的时候

与哪些语句一起使用:if 语句的条件执行体、for-in语句循环体、定义函数的函数体

11.1.3循环结构(while 语句与for in)

内置函数range()函数(内置函数:前面不用加任何前缀,可以直接使用的函数):用于生成一个整数序列;将range函数作为循环遍历的对象!

创建range对象的三种方式:

range(stop)	创建一个(0,stop)之间的整数序列,步长为1;
range(start,stop) 创建一个(start,stop)之间的整数序列,步长为1;
range(start,stop,step)

range类型的优点:不管range对象表示的序列有多长,所有range对象占用的内存空间是相同的,因为仅仅需要存储start和step,只有当用到range对象时,才会计算序列中的相关元素;

'''第一种创建方式:只有一个参数(括号里只给一个数)'''
rr = range(10)    # 默认从0开始,默认步长为1,不包括10
print(rr)   # range(0,10)  返回值是一个迭代对象
print(list(rr)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]   查看range对象中的整数队列
'''第二种创建方式:给了两个参数(括号里给了两个数)'''
rr1 = range(1,10)  # 指定了起始值,从1开始,到10结束不包括10,默认步长为1
print(rr1)   # range(1, 10)
print(list(rr1))   # [1, 2, 3, 4, 5, 6, 7, 8, 9]
'''第三种创建方式:给三个参数'''
rr2 = range(2,11,2)
print(rr2)
print(list(rr2))
'''判断指定的整数,在序列中是否存在  in 或 not in'''
print(2 in list(rr2))
print(10 not in rr2)

range()函数产生一个整数序列,是一个可迭代对象;

in 与 not in 判断整数序列中是否存在(不存在)指定的指数;

循环结构:

**while **

语法结构:

while  条件表达式:
		条件执行体(循环体)

选择结构的if与循环结构while的区别:

if是判断一次,条件为True执行一行;while是判断N+1次,条件为True执行N次;

while循环的执行流程:

四步循环法:初始变量、条件判断、条件执行体(循环体)、改变变量

# 计算0-4之间的累加和
sum = 0
'''初始化变量为0'''
i = 0
while i<=4:     # 条件判断
   sum = sum + i   # 条件执行体(循环体)
   i = i+1          # 改变变量
print(sum)
# 计算1-100之间的偶数和
i = 1
sum = 0
while i<=100:
    if i%2==0:
        sum+=i
    i+=1
print(sum)
# 2550
# 计算1-100之间的偶数和
i = 1
sum = 0
while i<=100:
    if not bool(i%2):   # 为0的布尔值为false,not false=true---执行;1的布尔值为true,not true=false--不执行!
        sum+=i
    i+=1
print(sum)

for in循环

in表达从(字符串、序列等)中一次取值,又称为遍历;

for in遍历的对象必须是可迭代对象;

语法结构:

for 自定义变量 in 可迭代对象
	循环体		
for i in range(1,10):
    print(i)    # 循环的次数

输出结果:

1
2
3
4
5
6
7
8
9

执行了10次,循环次数

for item in "Python":
    print(item)

输出结果:

P
y
t
h
o
n

如果在循环体中不需要自定义变量,可将自定义变量写为下划线 “_”;

for _ in range(5):
    print('人生苦短,我用python')
    
输出结果:
人生苦短,我用python
人生苦短,我用python
人生苦短,我用python
人生苦短,我用python
人生苦短,我用python
'''输出100-999之间的水仙花数;
举例:153=3**3+5**3+1**3
'''
for i in range(100,1000):
    ge=i%10
    shi=i//10%10
    bai=i//100
    # print(bai,shi,ge)
    if ge**3+shi**3+bai**3==i:
        print(i)

输出结果:

153
370
371
407

流程控制语句break

break语句用来结束循环结构,通常与分支结构if一起使用;举例用“for in”

# 从键盘录入密码,最多输入三次,如果正确就结束循环;

for i in range(3):	# 0 1 2
    secret = int(input('请输入密码:'))
    if secret==258096:
        break
    else:
        print('密码错误,请重新输入!')

输出结果:

请输入密码:123456
密码错误,请重新输入!
请输入密码:258096

举例用while:

i=1         # 初始化变量
while i<3:     # 条件判断
    secreat = int(input('请输入密码:'))  # 条件执行体
    if secreat==123456:
        break
    else:
        print('密码错误,请重新输入')
    i+=1             # 改变变量

输出结果:

请输入密码:45689
密码错误,请重新输入
请输入密码:123456

流程控制语句continue

用于结束当前循环,进入下一次循环通常与分支结构中的if一起使用;break是跳出当前循环

# 输入1-50之间的所有的5的倍数
for i in range(1,51):
    i*=5
    if i>50:
        break
    else:
        print(i)
我写的:嘻嘻

输出结果:

5
10
15
20
25
30
35
40
45
50

注意:在涉及到数字运算时要想到标准算数运算符!

for i in range(1,51):
    if not bool(i%5):
        print(i)
    else:
        continue
在视屏的启发下写的:嘻嘻   上面这个是错误的!,按照以下这样写:
for i in range(1,51):
    if not bool(i%5):
        print(i)
        
但是必须使用continue,那么就要转化种思路:什么样的数不是5的倍数


for i in range(1,51):-----
    if i%5!=0:            |
        continue----------
    print(i)
解释:当i为1时,判断1与5相除取余是否为0,不为0,continue,再到for i in range 循环判断...直到为0输出i

else语句

与else语句配合使用的三种情况:

第一种情况:
if...:
	...
else:
	...
第二种情况:
while ...:
	...
else:
	...
第三种情况:
for ...:
	...
else:
	...
	
while 与 for使用在有break或continue时,没有else
for i in range(3):
    secret = int(input('请输入密码:'))
    if secret==258096:
        break
    else:
        print('密码错误,请重新输入!')
else:
    print('对不起,三次密码均输入错误')
输出结果:
请输入密码:123
密码错误,请重新输入!
请输入密码:456
密码错误,请重新输入!
请输入密码:4789
密码错误,请重新输入!
对不起,三次密码均输入错误
i=0
while i<=2:
    pwd = int(input('请输入密码'))
    if pwd == 123456:
        break
    else:
        print('密码错误')
    i+=1
else:
    print('对不起,均错误')
请输入密码123
密码错误
请输入密码456
密码错误
请输入密码789
密码错误
对不起,均错误    
嵌套循环

循环结构中又嵌套了另外的完整的循环结构,其中内层循环作为外层循环的循环体执行

# 打印三行四列的矩形
'''
****
****
****
'''
for i in range(1,4):    # 行数3行
     for j in range(1,5):   # 列数4列
        print('*',end=' ')  # 不换行输出
     print()
输出结果:
* * * * 
* * * * 
* * * * 
解释:
	1 2 3 4  j列
1	* * * * 
2	* * * * 
3	* * * * 
i行
说明:当执行程序第一、二、三行时,i为1--j为1---打印   *
	 当执行程序第一、二、三行时,i为1--j为2---打印   * *
     ...  * * * *
                     i为2--j为1---打印  * * * *
            						   * 
'''打印九九乘法表,首先试着先把直角三角形打印出来'''
# 打印直角三角形
for i in range(1,10):    # 行数
    for j in range(1,i+1):    # 列数
        print(str(i)+'*'+str(j)+'='+str(i * j),end=' ')  # 不换行
    print()     # 换行
解释:
执行第一行时,i=1,
执行第二行时,j在(1,2)取1
执行第三行时,不换行输出第一行、第二行执行结果;为 *
执行第四行时,换行;* 之后换行,进行第二行的打印输出;

i=2  第二行输出
j(1,3)---j=1,j=2  第二行的第一列与第二列
不换行输出--* *
换行输出* *,进行第三行...

输出结果:

1x1=1
2x1=2 2x2=4
3x1=3 3x2=6 3x3=9
4x1=4 4x2=8 4x3=12 4x4=16
5x1=5 5x2=10 5x3=15 5x4=20 5x5=25
6x1=6 6x2=12 6x3=18 6x4=24 6x5=30 6x6=36
7x1=7 7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49
8x1=8 8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64
9x1=9 9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81

二层循环中的break和continue

用于控制本层循环;

break跳出本层循环,不影响后续的程序运行;continue

以下举例没看懂

for i in range(5):    # 循环次数0-4 5次
    for j in range(1,11):---------
        if j%2==0:                |----
            break                 |----内循环,输出的内容
        print(j,end=' ')----------
    print()
1 
1 
1 
1 
1 
没看懂在j取(1-10),为什么在这里是1与2!
for i in range(5):
    for j in range(1,11):<----
        if j%2==0:           |
            continue----------
        print(j,end=' ')
    print()
1 3 5 7 9 
1 3 5 7 9 
1 3 5 7 9 
1 3 5 7 9 
1 3 5 7 9 

总结:循环结构中的while用于次数不固定的循环,初始条件不成立,一次都执行;for in用于遍历可迭代对象;

break结束当前循环结构;continue结束当前循环进入下一次循环;

12 列表

12.1为什么需要列表?

变量可以存储一个元素,而列表可以存储N多个元素,程序可以方便的对这些数据进行整体性操作;列表相当于其他语言中的数组

书包---列表 书本、笔盒...---对象

lst = ['hello','world',89]
print(id(lst))
print(type(lst))
print(lst)
输出结果:
2625645986112
<class 'list'>
['hello', 'world', 89]
解释:
lst 的id是112,类型是列表,value是'hello','world',89
那么,每一个对象也都有id,type,value

12.2列表的创建
'''创建列表的第一种方式---中括号[],元素之间用英文逗号相隔'''
lst = ['hello','world',90]
'''创建列表的第二种方式---使用内置函数list()'''
lst1 = list(['hello','world',90])
解释:内存示意图
                 -------->|hello(id,type,value)

(id,type,value)lst------->|world(id,type,value)

                  ------->|90(id,type,value)
    
空列表创建:
lst=[]
lst=list()   与lst=list([])  输出一样,但id不一样
12.4列表特点

列表元素按顺序有序排序;

索引映射唯一一个数据

索引		-7		 -6      -5    -4      -3      -2     -1
数据   'hello'  'world'   123   88.6   'world'   125   world
索引       0        1       2     3        4       5     6

列表可以存储重复数据;

任意数据类型混存;

根据需要动态分配和回收内存

12.5列表的查询--获取列表指定元素的索引

(元素-->索引)

lst = ['hello','world',98,'hello']
# 查询列表中存在N个相同元素,默认只返回相同元素的第一个元素
print(lst.index('hello')) # 输出结果0
# 如果查询的元素在列表中不存在,则会报错
# print(lst.index('99'))      # ValueError
# 在指定的start与stop之间寻找
print(lst.index('hello',1,4))   # 1-4 不包括4    输出结果3
12.6获取列表指定的元素

获取列表中的单个元素:索引---->元素

正向索引从0到N-1

逆向索引从-N到-1

指定的索引不存在,IndexError

lst = ['hello','world',98,'hello','wwe',789]
# 获取索引为2的元素
print(lst[2])   # 98
# 获取索引为-3的元素
print(lst[-3])    # hello
# 获取的索引元素超出范围
# print(lst[-10])     # IndexError

获取列表中的多个元素:切片

语法格式:

列表名[start : stop : step]

切片操作:

切片的结果----原列表切片的拷贝

切片范围:(start : stop) 前包后不包

step 默认为1,简写(start : stop)

step 为正数:

( : stop : step)      切片的第一个元素默认是列表的第一个元素

(start : : step)		切片的最后一个元素默认是列表的最后一个元素

​							(从start开始往后计算切片)

lst = [10,20,30,40,50,60,70,80,90]
# start=1,stop=6(不包括索引6的元素),step=1
print('原列表',id(lst))
lst1 = lst[1:6:1]   # 默认步长为1,lst[1:6:]
print(lst1)
print('切片后:',id(lst1))
print(lst[1:6])     # 默认步长为1
print(lst[1:6:])
print(lst[1:6:2])
print(lst[:6:2])
print(lst[1::2])    # 从索引为1的到列表元素最后

输出结果:
原列表 1878149972288
[20, 30, 40, 50, 60]
切片后: 1878149975552
[20, 30, 40, 50, 60]
[20, 30, 40, 50, 60]
[20, 40, 60]
[10, 30, 50]
[20, 40, 60, 80]
step为负数:
( : stop:step )      切片的第一个元素默认是列表的最后一个元素

(start ::step)		切片的最后一个元素默认是列表中的第一个元素

​								(从stop开始往前计算切片)
举例:
lst = [10,20,30,40,50,60,70,80,90]
print('------step为负数-----')
print('原列表',lst)
print(lst[::-1])
print(lst[7::-1])
print(lst[6:0:-2])

输出结果:
------step为负数-----
原列表 [10, 20, 30, 40, 50, 60, 70, 80, 90]
[90, 80, 70, 60, 50, 40, 30, 20, 10]
[80, 70, 60, 50, 40, 30, 20, 10]
[70, 50, 30]
12.7 列表元素的判断及遍历

遍历:将列表中的元素依次输出。

判断指定元素在列表中是否存在---in与not in

元素 in 列表名
元素 not in 列表名

举例:

lst = [10,20,'python','world']
print(10 in lst)
print('hello' not in lst)
输出结果:

True
True

列表元素的遍历:

for  迭代变量  in  列表名: # 目前学习的可迭代对象有列表与字符串。
		操作
lst = [10,20,'python','world']
for i in lst:
    print(i)
输出结果:
10
20
python
world
12.8列表元素的添加、删除、修改、排序操作

列表元素添加:

append():在列表末尾添加一个元素

# 在列表末尾添加一个元素
lst=[123,'rrt','hello',99]
print('原列表',id(lst))
lst.append(100)
print('添加后的列表',lst,id(lst))

# lst2=['hello','world']
# lst.append(lst2) # 将lst2作为整个列表加在lst里的最后一个元素后面
# print(lst) # [123, 'rrt', 'hello', 99, 100, ['hello', 'world']]

输出结果:
原列表 1503804080448
添加后的列表 [123, 'rrt', 'hello', 99, 100] 1503804080448
[123, 'rrt', 'hello', 99, 100, ['hello', 'world']]

extend():在列表元素末尾以此添加多个元素

# 在列表末尾至少添加一个元素--extend()
lst=[123,'rrt','hello',99,100]
lst2=['hello','world']
lst.extend(lst2)  # 将lst2里的元素分别加在lst元素后面
print(lst) # [123, 'rrt', 'hello', 99, 100, 'hello', 'world']

输出结果:
[123, 'rrt', 'hello', 99, 100, 'hello', 'world']

insert():通过索引在列表的任意位置添加一个元素

lst = ['hello','world',99,23,'pwd']
lst.insert(2,'不要学我')    # 在指定所以之前添加元素
print(lst)

输出结果:
['hello', 'world', '不要学我', 99, 23, 'pwd']

切片:在列表的任意位置添加至少一个元素

lst=['hello', 'world', '不要学我', 99, 23, 'pwd']
lst2=[True,False,'hello']
lst[3:]=lst2    # 索引为3(包括)切开之后的不要,加上lst2的
print(lst)
输出结果:
['hello', 'world', '不要学我', True, False, 'hello']

列表元素删除:remove()、pop()、切片、del

remove():根据元素删除

一次删除一个指定元素

lst = [10,20,10,20,50,60,30]
lst.remove(50)
print(lst)
输出结果:
[10, 20, 10, 20, 60, 30]

重复元素只删除第一个;

lst = [10,20,10,20,50,60,30]
lst.remove(20)
print(lst)
输出结果:
[10, 10, 20, 50, 60, 30]

元素不存在的话ValueError

lst = [10,20,10,20,50,60,30]
lst.remove(70)
print(lst)
输出结果:
ValueError: list.remove(x): x not in list

pop():根据索引删除

删除一个指定索引位置上的元素

lst = [10,20,10,20,50,60,30]
lst.pop(0)
print(lst)
输出结果:
[20, 10, 20, 50, 60, 30]

不指定索引,默认删除列表中中最后一个元素

lst = [10,20,10,20,50,60,30]
lst.pop()
print(lst)
输出结果:
[10, 20, 10, 20, 50, 60]

指定索引不存在,ValueError

切片:一次至少删除一个元素,将产生一个新的列表元素

# 删除至少一个元素,产生一个新的列表对象
lst = [10,20,10,20,50,60,30]
new_lst = lst[1:3]
print('原列表',id(lst),lst)
print('新列表',id(new_lst),new_lst)

# 不产生新的列表,而是删除原有列表中的内容
lst[1:3]=[]
print(lst,id(lst))

输出结果:
原列表 2727795245376 [10, 20, 10, 20, 50, 60, 30]
新列表 2727795190080 [20, 10]
[10, 20, 50, 60, 30] 2727795245376

clear():清楚列表中的所有元素

lst = [10,20,10,20,50,60,30]
lst.clear()
print(lst)
输出结果:
[]

del:删除列表

列表元素修改:

为指定索引的元素赋予一个新值(一次修改一个值)

lst = [10,20,10,20,50,60,30]
lst[5]=200
print(lst)
输出结果:
[10, 20, 10, 20, 50, 200, 30]

为指定的切片赋予一个新值(赋予多个新值)

lst = [10,20,10,20,50,60,30]
lst[:4]=[100,200,100]
print(lst)
输出结果:
[100, 200, 100, 50, 60, 30]

列表元素排序

1.调用sort()方法,列表中的所有元素默认按照从小到大(升序)顺序进行排序,可以指定reverse=True,进行降序排序;

lst = [20,50,98,69,45,60,30]
print('排序前:',lst,id(lst))
lst.sort()     # 默认升序,reverse=False
print('排序后:',lst,id(lst))
lst.sort(reverse=True)  # 降序
print('再排序后:',lst,id(lst))
输出结果:
排序前: [20, 50, 98, 69, 45, 60, 30] 1996126241088
排序后: [20, 30, 45, 50, 60, 69, 98] 1996126241088
再排序后: [98, 69, 60, 50, 45, 30, 20] 1996126241088

2.调用内置函数sorted()升序,可以指定reverse=True,进行降序排序,原列表不发生变化;(产生一个新的列表对象)

lst = [20,50,98,69,45,60,30]
print('排序前:',lst,id(lst))
lst1=sorted(lst)     # 默认升序,reverse=False
print('排序后:',lst1,id(lst1))
jixu=sorted(lst,reverse=True)  # 降序
print('再排序后:',jixu,id(jixu))
输出结果:
排序前: [20, 50, 98, 69, 45, 60, 30] 2350573895936
排序后: [20, 30, 45, 50, 60, 69, 98] 2350576623040
再排序后: [98, 69, 60, 50, 45, 30, 20] 2350573896512
12.9列表生成式--生成列表的公式
语法格式:
[i*i for i in range(1,10)]
i*i 表示列表元素的表达式;
i 自定义变量
range(1,10) 可迭代对象
# 注意事项:“表示列表元素的表达式”中通常包含自定义变量

举例:

lst = [i for i in range(1,10)]  # 将1-9的序列赋值给i,在以列表的格式输出
print(lst)
输出结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]

输入2 4 6 8 10的列表

lst = [i*2 for i in range(1,6)]  # 将1-9的序列赋值给i,在以列表的格式输出
print(lst)
输出结果:
[2, 4, 6, 8, 10]

13 字典

13.1什么是字典?

是python内置的数据结构之一,与列表一样是一个可变序列(数据结构可执行增删改操作);不可变序列:整数、字符串(不进行增删改操作)

以键值对的方式存储数据,字典是一个无序的序列;键不可重复。

13.2字典的原理

实现原理:数据在字典中存储的时候会进行哈希算法,将key进行哈希计算存储位置,所以key必须是一个不可变序列,根据key查找value所在的位置

13.3字典的创建

1.使用花括号{}

score = {'张三':100,'李四':98,'王五':45}
空字典:
dcc = {}

2.使用内置函数dict()

dic(name='jack',age=20)
13.4字典的查询操作

字典中元素的获取:根据键获取值

1.[]     举例:score['张三']
2.get()方法     举例:score.get('张三',66)# 如果张三不存在则返回默认值66
二者取值的区别:
[]如果字典中不存在指定的key,抛出keyError异常
get()方法取值,如果字典中不存在指定的key,并不会抛出KeyError,而是返回None,可以通过参数设置默认的value,以便指定的key不存在返回

key值判断

in 指定的key在字典中存在返回True;
not in 指定的key在字典中不存在返回True
score = {'张三':100,'李四':98,'王五':45}
print('张三' in score)
print('张三' not in score)

输出结果:
True
False

获取字典视图的三种方法:

1.keys()----获取字典中所有的key

score = {'张三':100,'李四':98,'王五':45}
key = score.keys()
print(key)
print(type(key))
print(list(key))

输出结果:
dict_keys(['张三', '李四', '王五'])
<class 'dict_keys'>
['张三', '李四', '王五']

2.values()-----获取字典中所有的value

score = {'张三':100,'李四':98,'王五':45}
value = score.values()
print(value)
print(type(value))
输出结果:
dict_values([100, 98, 45])
<class 'dict_values'>

3.items()------获取字典中所有的key,value对

score = {'张三':100,'李四':98,'王五':45}
ii = score.items()
print(ii)
print(type(ii))
输出结果:
dict_items([('张三', 100), ('李四', 98), ('王五', 45)])
<class 'dict_items'>

字典元素的遍历:

for item in score:# 获取的是键,其中item是自定义变量
	print(item)
    
score = {'张三':100,'李四':98,'王五':45}
for item in score:
    print(item)     # 获取的是键
输出结果:
张三
李四
王五

score = {'张三':96,'李四':100,'麻七':100}
for item in score:
    # print(item)
    # print(score[item]) 根据key获取vlaue
    print(score.get(item))
输出结果:
96
100
100
13.5字典元素的增删改操作

字典元素的删除:

del score['张三']

score.clear() # 清空字典中的元素 {}

score = {'张三':100,'李四':98,'王五':45}
del score['张三']   # 删除指定的键值对
print(score)
输出结果:
{'李四': 98, '王五': 45}

字典元素的新增:

score['jack']=90

也可以修改元素的值:score['李四']=60

score = {'张三':100,'李四':98,'王五':45}
score['小二'] = 90
print(score)
输出结果:
{'张三': 100, '李四': 98, '王五': 45, '小二': 90}

字典的特点:

1.字典中的所有元素都是一个key-value对,key不可以重复,value可以重复;

2.字典中的元素是无序的;

3.字典中的key必须是不可变对象;

4.字典也可以根据需要动态地伸缩

5.字典会浪费较大的内存,是一种使用空间换时间的数据结构

13.6字典推导式

字典生成式:

内置函数zip():用于将可迭代的对象(可以使用for in循环遍历的对象)作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表

items = ['Fruits','Book','Other']
prices = [96,78,85]
zz = zip(items,prices)
print(list(zz))
输出结果:
[('Fruits', 96), ('Book', 78), ('Other', 85)]


tool = ['Fruits','Book','Others']
prace = [98,56,78]
di={kes:vaus for kes,vaus in zip(tool,prace)}
print(di)
输出结果:
{'Fruits': 98, 'Book': 56, 'Others': 78}

items = ['Fruits','Book','Other']
prices = [96,78,85]
pz={items.upper():prices for items,prices in zip(items,prices)}
# 解释:
items.upper():prices
items,prices    
zip(items,prices)
print(pz)
输出结果:
{'FRUITS': 96, 'BOOK': 78, 'OTHER': 85}

14 元组

14.1 元组介绍

python内置的数据结构之一,是一个不可变序列;

不可变序列与可变序列:

不可变序列:字符串、元组(没有增删改操作)

'''不可变序列:字符串,元组...内存地址在增删改之后发生变化'''
s = '哈哈'
s1 = s+'hello'
print(s,id(s))   # 2426108766224
print(s1,id(s1))	# 2426108766416

输出结果:
哈哈 2426108766224
哈哈hello 2426108766416

可变序列:列表、字典(可以对序列执行增删改操作,对象地址不发生更改)

'''可变序列:列表,字典...内存地址在增删改之后没发生变化'''
lst = [50,'hello',56,80]
print(lst,id(lst))      # 1847814275392
lst.append(99)
print(lst,id(lst))      # 1847814275392

输出结果:
[50, 'hello', 56, 80] 1847814275392
[50, 'hello', 56, 80, 99] 1847814275392
14.2元组的创建方式:
tup = ('python','world',90)   
print(tup,type(tup))

tup1 = tuple(('python','world',90))
print(tup1,type(tup1))

输出结果:
('python', 'world', 90) <class 'tuple'>
('python', 'world', 90) <class 'tuple'>

# 注意
tup = ('python','world',90)   # 也可以写成tup='python','world',90
如果是一个元素,比如:tt = ('poop'),输出的类型是str,所以“只包含一个元组的元素需要使用逗号和小括号” ,逗号不能省略!!!
tt=('poop')
print(tt,type(tt))  # poop <class 'str'>

tt=('poop',)
print(tt,type(tt)) # ('poop',) <class 'tuple'>
# 创建空元组
tt=()
tt=tuple()
# 创建空字典
dd={}
dd=dic()
14.2元组的遍历

元组是可迭代对象,所以可以使用for...in进行遍历(走一遍)

ttp=('python',980,'world')
print(ttp[0]) # 获取元组方式
for i in ttp:
    print(i)
输出结果:
python
python
980
world

15 集合

15.1 集合的概述与创建:

集合是什么:

Python语言提供的内置数据结构;

与列表、字典一样都属于可变类型(增删改查)的序列;

集合是没有value的字典;

向集合里放数据元素会通过哈希函数计算存储位置,所以第一个放进的元素未必在第一位。(集合元素是无序的)

集合的创建方式

1.直接{} s={'python','hello',90},存储单个元素,不允许重复.

s={6,6,7,4,5,6,4,3,4,3} # 将重复元素去掉
print(s)
输出结果:
{3, 4, 5, 6, 7}

2.使用内置函数

s = set(range(6))
print(s)   # {0, 1, 2, 3, 4, 5}

s = set([2,5,6,2,4,6,3,2])
print(s,type(s)) # {2, 3, 4, 5, 6} <class 'set'>

s = set((34,6,78,90))
print(s,type(s))  # {78, 34, 90, 6} <class 'set'>

s = set('python')
print(s,type(s)) # {'y', 'o', 'p', 'n', 'h', 't'} <class 'set'>

s = set({34,56,78,11,22,22})
print(s,type(s)) # {34, 22, 56, 11, 78} <class 'set'>

s = set()   # 定义一个空集合,如果是s={}的话数据类型是字典!
print(s,type(s)) # set() <class 'set'>
15.2 集合的相关操作:

集合元素的判断操作:in或not in

s = {1,2,5,9,80,100}
print(1 in s)
print(100 not in s)
True
False

集合元素的新增操作:

1.调用add()方法,一次添加一个元素

2.调用update()方法至少添加一个元素

s = {1,2,5,9,80,100}
s.add(12)
print(s) # {1, 2, 100, 5, 9, 12, 80}

s = {1,2,5,9,80,100}
s.update({300,20,800,70})
print(s) # {800, 1, 2, 100, 5, 70, 9, 300, 80, 20}

s = {1,2,5,9,80,100}
s.update(['op',78,66])
print(s) # {1, 2, 'op', 100, 5, 66, 9, 78, 80} 

s = {1,2,5,9,80,100}
s.update((65,88,99,'oh'))
print(s) # {1, 2, 65, 100, 5, 99, 9, 80, 88, 'oh'}

集合元素的删除操作:

调用remove()方法,一次删除一个指定的元素,如果指定的元素不存在抛出keyerror;

s = {1,2,5,9,80,100}
s.remove(100)
print(s) # {1, 2, 5, 9, 80}

s = {1,2,5,9,80,100}
s.remove(90)
print(s) # KeyError

调用discard()方法,一次删除一个指定的元素,如果指定的元素不存在不抛出异常;

s = {1,2,5,9,80,100}
s.discard(90)
print(s) # {1, 2, 100, 5, 9, 80} 有就删除,没有不报错

调用pop()方法,一次只删除一个任意的元素;

s = {1,2,5,9,80,100,11}
s.pop()  # 不能添加参数,规定无参;TypeError
print(s) # {2, 100, 5, 9, 11, 80}

调用clear()方法,清空集合;

s = {1,2,5,9,80,100,11}
s.clear()  #无参,清空
print(s) # set()
15.3 集合间的关系

两个集合是否相等:可以使用运算符==或!=进行判断

s1={10,20,30,40}
s2={40,30,10,20}
print(s1==s2)  # True
print(s1!=s2)  # False
集合里的元素是无序列,输出的顺序不会决定存储顺序(元素内容相同集合即可)

一个集合是否是另一个集合的子集:可以调用方法issubset进行判断;B是A的子集

s1={10,20,30,40}
s2={40,30,10,20,60,100}
s3={10,20,30,90,100}
se=s1.issubset(s2)
see=s3.issubset(s1)
print(se)  # True
print(see)   # False

一个集合是否是另一个集合的超集:可以调用方法issuperset进行判断;A是B的超级

s1={10,20,30,40}
s2={40,30,10,20,60,100}
s3={10,20,30,90,100}
se=s2.issuperset(s1)
see=s2.issuperset(s3)
print(se)  # True
print(see)   # False

两个集合是否没有交集:可以调用方法isdisjoint进行判断

s1={10,20,30,40}
s2={40,30,10,20,60,100}
s3={400,500,45}
se=s2.isdisjoint(s1)
see=s2.isdisjoint(s3)
print(se)  # Flase  有交集为flase
print(see)   # True   无交集为True
15.4 集合的数据操作

集合的数学关系:

交集:

s1={50,45,89,40,10}
s2={40,89,50,10,30}
print(s1.intersection(s2))
print(s1 & s2)      # intersection()与&都是交集操作
输出结果:
{40, 89, 10, 50}
{40, 89, 10, 50}

并集:

s1={50,45,89,40,10}
s2={40,89,50,10,3099,66}
print(s1.union(s2))
print(s1 | s2)      # union()与|都是并集操作
输出结果:
{66, 40, 10, 45, 50, 89, 3099}
{66, 40, 10, 45, 50, 89, 3099}

差集:

s1={50,45,89,40,10}
s2={40,89,50,10,3099,66}
print(s1.difference(s2))   # s1-s2   {45}
print(s2.difference(s1))    # s2-s1  {66, 3099}  在s2的集合里将s1的元素全部去掉
print(s1 - s2)      # difference()与-都是差集操作
输出结果:
{45}
{45}

对称差集:

s1={50,45,89,40,10}
s2={40,89,50,10,3099,66}
print(s1.symmetric_difference(s2))   # 去掉相同的元素,余留下来的元素
print(s1 ^ s2)      # symmetric_difference()与^都是对称差集操作
输出结果:
{66, 3099, 45}
{66, 3099, 45}
15.5 集合生成式

用于生成集合的公式:

{i*i for i in range(10)}
i*i表示集合元素的表达式
i自定义变量
range(10)可迭代对象(迭代:轮流代替)、
将{}修改为[]就是列表生产式
没有元组生成式,因为元组是不可变数据类型;
sett = {i*i for i in range(10)}   # for i in range(10) 默认0-9
print(sett)   # 集合元素是无序的
输出结果:
{0, 1, 64, 4, 36, 9, 16, 49, 8125}

列表、字典、元组、集合总结

数据类型 是否可变 是否重复 是否有序 定义符号
列表(list) 可变 可以重复 有序 []
元组(tuple) 可变 可以重复 有序 ()
字典 可变 key不可重复;value可重复 无序 {key:"value"}
集合 可变 不可重复 无序 {}
image-20220424101339229

16 字符串

16.1 字符串的驻留机制

字符串:在python中字符串是基本数据类型,是一个不可变的字符序列;

a='python'
aa="python"
aaa='''python'''
print(a,id(a))
print(a,id(aa))
print(a,id(aaa))
输出结果:
python 1481882442352
python 1481882442352
python 1481882442352
解释:
创建aa字符串的时候,发现存储中有相同的字符串,不会再开辟新的存储空间,而是把该字符的地址付给新创建的变量。

字符串的驻留机制:仅保存一份相同的且不可变的字符串方法,不同的值被存放在字符串的驻留池中,python的驻留机制对相同的字符串只保存一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符的地址赋给新创建的变量。

驻留机制的几种情况(交互模式):

字符串的长度为0或1时;

>>> s1=''   # 字符长度为0
>>> s2=''
>>> s1 is s2
True
>>> s1='%'   # 字符长度为1
>>> s2='%'
>>> s1 is s2
True

符合标识符的字符串(字母,数字,下滑线);

>>> s1='abc%'  # 不符合字符串
>>> s2='abc%'
>>> s1==s2
True
>>> s1 is s2
False
>>> id(s1)
2277190557360       ----------- 内存地址不一样!
>>> id(s2)
2277190557424       -----------

>>> s1='abcx'
>>> s2='abcx'
>>> s1==s2
True
>>> s1 is s2      ---------内存地址一样!
True

字符串只在编译时进行驻留,而非运行时;

>>> a='abc'    
>>> b='ab'+'c'  # b的值在连接之前就完成了
>>> c=''.join(['ab','c'])  # c是程序运行的时候对列表中的数据进行连接的
>>> a is b
True
>>> a is c
False   ----------------注意这里!!!
>>> c
'abc'
>>> type(c)
<class 'str'>
>>> type(a)
<class 'str'>

[-5,256]之间的整数数字;

>>> a=-5
>>> b=-5
>>> a is b
True
>>> a=-6
>>> b=-6
>>> a is b
False

sys中的inter方法强制2个字符串指向同一个对象;

>>> import sys
>>> a='abc%'
>>> b='abc%'
>>> a is b
False
>>> a=sys.intern(b)
>>> a is b
True

pycharm对字符串进行了优化处理;

字符串驻留机制的优缺点:

当需要值相同的字符串时可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升雄安率和节约内存,因此拼接字符串和修改字符串是会比较影响性能的;

在需要进行字符串拼接时建议使用str类型的join方法,而非+join()方法是先计算出所有字符串的长度,然后再拷贝,只new一次对象,效率要比“+”效率高。

16.2 字符串的常用操作

查询操作方法:

功能 方法名称 作用
查询方法 index() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
rindex() 查找子串substr最后出现的位置,如果查找的子串不存在时,则抛出valueerror
find() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1
rfind() 查找子串substr最后出现的位置,如果查找的子串不存在时,则返回-1
两者的区别就是:找不到出现的位置时,报错结果不一样;
s='hello,hello'
print(s.index('lo'))
print(s.rindex('lo'))   # 逗号也是一个索引值
输出结果:
3
9

s='hello,hello'
print(s.find('p'))
print(s.rfind('lo'))
输出结果:
-1
9

解释:

image-20220424140254120

大小写转换操作的方法:

功能 方法名称 作用
大小写转化 upper() 把字符串中所有字符都转成大写字母
lower() 把字符串中所有字符都转成小写字母
swapcase() 把字符串中所有大写字母转换成小写字母,把所有小写字母转换成大写字母
capitalize() 把第一个字符转换成大写,把其余字符转换为小写
title() 把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写
s='hello,python'
a=s.upper()
print(a,id(a))
print(s,id(s))
输出函数:
HELLO,PYTHON 1845603946160
hello,python 1845603572336
解释:字符串是不可变数据类型,转换成大写内存位置不一样,开辟了另一个存储空间,产生新的字符串对象。	

s='hello,python'
a=s.lower()    # 转换之后会产生一个新的字符串对象
print(a,id(a))
print(s,id(s))
print(a==s)
print(a is s)    # 内存位置不一致;
输出结果:
hello,python 2168620011248
hello,python 2168619974384
True
False

s2='hello,Python'
print(s2.swapcase())   # HELLO,pYTHON
print(s2.title())   # Hello,Python
print(s2.capitalize())  # Hello,python

内容对齐操作的方法

功能 方法名称 作用
字符串对齐 center() 居中对齐,第一个参数指定宽度,第二个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
ljust 左对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
rjust 右对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
zfill() 右对齐,左边用0填充,该方法只接受一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身。
s='hello,python'

print(s.center(20,'*'))   # ****hello,python****
print(s.ljust(20,"*"))    # hello,python********
print(s.center(10,'*'))   # hello,python
print(s.center(20))
输出结果:
****hello,python****
hello,python********
hello,python
    hello,python 


print(s.rjust(20,'*'))
print(s.rjust(20))
print(s.ljust(10,'*'))
输出结果:
********hello,python
        hello,python
hello,python

print(s.zfill(20))
print(s.zfill(10))
print('-8901'.zfill(8))
输出结果:
00000000hello,python
hello,python
-0008901

劈分操作的方法:

功能 方法名称 作用
字符串的劈分 split() 从字符串的左边开始劈分,默认的劈分字符串是空格字符串,返回的值都是一个列表
以通过参数sep指定劈分字符串的是劈分符
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的字串会单独做为一部分
rsplit() 从字符串的右边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表
以通过参数sep指定劈分字符串的是劈分符
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的字串会单独做为一部分
strip() 方法 用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
s='hello world Python'
lst=s.split()
print(lst)
输出结果:
['hello', 'world', 'Python']

s1='hello|world|python'
lst1=s1.split(sep='|')
print(lst1)
输出结果:
['hello', 'world', 'Python']

s1='hello|world|python'
lst1=s1.split(sep='|',maxsplit=1)
print(lst1)
输出结果:
['hello', 'world|python']
s='hello world Python'
lst=s.rsplit()
print(lst)
输出结果:
['hello', 'world', 'Python']

s1='hello|world|python'
lst1=s1.rsplit('|')
print(lst1)
输出结果:
['hello', 'world', 'python']

s1='hello|world|python'
lst1=s1.rsplit(sep='|',maxsplit=1)
print(lst1)
输出结果:
['hello|world', 'python']

判断字符串操作的方法

功能 方法名称 作用
判断字符串的方法 isidentifier() 判断指定的字符串是不是合法的标识符
isspace() 判断指定的字符串是否全部由空白字符组成(回车、换行、水平制表符)
isalpha() 判断指定的字符串是否全部由字母组成
isdecimal() 判断指定字符串是否全部由十进制的数字组成
isnumeric() 判断指定的字符串是否全部由数字组成
isalnum() 判断指定的字符串是否全部由字母和数字组成
s='hello,python'
print(s.isidentifier())  # False
print( 'hello'.isidentifier())  # True
print('张三_'.isidentifier())   # True
print('张三_123'.isidentifier())   # True

print('\t'.isspace())  # True
print('abc'.isalpha())   # True
print('张三'.isalpha())   # True
print('张三1'.isalpha())   # Flase

print('123'.isdecimal())    # True
print('123四'.isdecimal())    # Flase
print('ⅡⅡⅡ'.isdecimal())     # Flase

print('123'.isnumeric())   # True
print('123四'.isnumeric())   # True
print('ⅡⅡⅡ'.isnumeric())     # True
print('abc1'.isalnum())   # True
print('张三123'.isalnum())   # True
print('abc!'.isalnum())    # False

字符串操作的其它方法

功能 方法名称 作用
字符串替换 replace() 第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可以通过第三个参数指定最大替换次数
字符串的合并 join() 将列表或元组中的字符串合并成一个字符串
s='hello,Python'
print(s.replace('Python','java'))

s1='hello,Python,Python,Python'
print(s1.replace('Python','java'))

print(s1.replace('Python','java',2))

输出结果:
hello,java
hello,java,java,java
hello,java,java,Python

lst=['hello','java','python']
print('|'.join(lst))
输出结果:
hello|java|python

lst=['hello','java','python']  -----列表
print(' '.join(lst))
输出结果:
hello java python

tup=('hello','java','python') -------元组
print(' '.join(tup))
输出结果:
hello java python


print('*'.join('python'))
输出结果:
p*y*t*h*o*n
16.3 字符串的比较

字符串的比较操作:

运算符:>,<=,<,<=,==,!=

比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,以此比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较;

比较原理:两个以上字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr,调用内置函数chr时指定ordinal value可以得到其对应的字符。

print('apple'>'app')  # True
print('apple'>'banana')  # False
print(ord('a'),ord('b'))  # 获取字符的原始值   97 98
print(ord('马'))   # 39532
print(chr(97),chr(98))  # 获得原始值所对应的字符  a b

print(chr(39532))   # 马


== 比较的是value;is比较的是id(内存地址)是否相等
a=b='python'
c='python'
print(a==b)  # True
print(b==c)    # True
print(a==c)   # True

print(a is b)   # True
print(a is c)    # True
print(b is c)     # True

print(id(a))   # True  1920823049840
print(id(c))   # True   1920823049840
print(id(a))    # True   1920823049840

16.4 字符串的切片操作

字符串是不可变类型,不具备增删改操作,切片操作将产生新的对象

切片:
[start:end:step]  步长是以索引为单位的
s='hello,python'
s1=s[:5]   # 由于没有指定起始位置,默认从索引值0
s2=s[6:]
s3='!'
ss=s1+s3+s2

print(s1)
print(s2)
print(ss)

print(id(s1),type(s1))
print(id(s2),type(s2))
print(id(s3),type(s3))
print(id(ss),type(ss))

输出结果:
hello
python
hello!python
2858431575024 <class 'str'>
2858431575088 <class 'str'>
2858431526000 <class 'str'>
2858431575152 <class 'str'>


s='hello,python' 
print(s[1:5:1])   # ello   从索引为1开始到索引为5,不包含索引为5的,步长为1;

print(s[::2])  # 索引为0,2,4,6,8,10
				# hlopto

print(s[::-1])   # 输出:nohtyp,olleh
# 默认从从字符串的最后一个元素开始,到字符串的第一个元素

print(s[-6::1])   # python
16.5 格式化字符串

字符串的拼接格式

两种方式:

%作占位符,%s:字符串,%i或%d:整数,%f:浮点数。

# %做占位符
name='张三'
age=3
print('我叫%s,今年%d岁' % (name,age))
输出结果:
我叫张三,今年3岁
image-20220427101407941

{}作占位符,

image-20220427101450968
# {}做占位符
name='张三'
age=3
print(f'我叫{name},今年{age}岁')
# f-string格式
print('我叫{0},今年{1}岁'.format(name,age))
输出结果:
我叫张三,今年3岁
我叫张三,今年3岁

表示的精度和宽度

print('%10d' % 66)  # 10 表示的是宽度
输出结果:
        66
    
print('%f' % 3.1415926)
print('%.3f' % 3.1415926)
print('%10.3f' % 3.1415926) # 宽度为10,精度为小数点后3位
输出结果:
3.141593
3.142
     3.142

print('{0}'.format(3.1415926))
输出结果:
3.1415926

print('{0:.3}'.format(3.1415926))  # 表示总共3位数
输出结果:
3.14

print('{0:.3f}'.format(3.1415926))
输出结果:
3.142

print('{0:10.3f}'.format(3.1415926)) # 宽度为10位,保留三位小数
输出结果:
     3.142
16.6 字符串的编码转化

为什么需要字符串的编解码

image-20220427140209747

编码与解码的方式

编码:将字符串转化为二进制数据(bytes)

解码:将bytes类型的数据转化成字符串类型

# 编码格式
s='天涯共此时'
print(s.encode(encoding='gbk'))  # 在gbk这种编码格式中一个中文占2个字节
print(s.encode(encoding='utf-8'))  # 在utf-8这种编码格式中一个中文占3个字节
输出结果:
b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'

# 解码格式
byte=s.encode(encoding='gbk')
print(byte.decode(encoding='gbk'))  # byte代表的是二进制数据
输出结果:
天涯共此时

byte=s.encode(encoding='utf-8')
print(byte.decode(encoding='utf-8'))  # byte代表的是二进制数据
输出结果:
天涯共此时
image-20220427143221106

17 函数

17.1函数的创建与调用

函数的定义:函数就是执行特定任务和以完成特定功能的一段代码(榨汁机);

为什么使用函数:复用代码,隐藏实现细节,提高可维护性,提高可读性便于调试;

函数的创建:
1 def 函数名 ([输入参数]): # 函数名符合标识符的规范自命名
2        函数体				# 实现功能
3	  [return xxx]	# 接收结果的容器(变量)

4 def calc(a,b):
5     c=a+b
6    return c	# 结束函数体并将结果提交,提交给函数的调用处

7 res = calc(99,999)    # 调用
8 print(res)
输出结果:
1098

解释:
当执行在第7行的时候,将值赋值给a与b输出的结果给调用处打印输出
17.2函数的参数传递
形式参数(形参)
def calc(a,b):  # a,b称为形式参数,形式参数在函数的定义处
实际参数(实参)
res = calc(99,999) # 10,20称为实参,实参在函数的调用处

函数调用的参数传递方式:

位置实参:根据形参对应的位置进行实参传递
res = calc(99,999)
关键字实参:根据形参名称进行实参传递
res = calc(b=999,a=99)    # 等号左侧的字母称为关键字参数

函数参数传递调用的内存分析:

传参的可变对象与不可变对象

# 定义函数
def fun(arg1,arg2):
    print('arg1',arg1)
    print('arg2',arg2)
    arg1=100
    arg2.append(10)
    print('arg1', arg1)
    print('arg2', arg2)
# 调用函数
n1=11
n2=[90,50,78]
print('n1',n1)
print('n2',n2)
fun(n1,n2)   # 位置传参,实参名称可以与形参名称不一致
print('n1',n1) # n1=11,
print('n2',n2)
'''在函数调用的过程中,进行参数的传递
如果是不可变对象n1,在函数体的修改不会影响实参的值,arg1的值改为100,不会影响;
如果是可变对象n2,在函数体的修改下会影响实参的值,arg2的列表中append(10),会影响n2的值'''

输出结果:
n1 11
n2 [90, 50, 78]
arg1 11
arg2 [90, 50, 78]
arg1 100
arg2 [90, 50, 78, 10]
n1 11
n2 [90, 50, 78, 10]
17.3函数的返回值
函数的返回值:
1.如果函数没有返回值(函数执行完毕之后,不需要给调用处提供数据),return可以省略不写;
def fun1():
    print('hello')
    return    # 可以省略不写

fun1()
输出结果:
hello
2.函数的返回值如果是1个,直接返回原类型
def fun1():
    return 'hello'

stt=fun1()
print(stt)
输出结果:
hello
3.函数的返回值,如果是多个,返回的结果为元组
def fun2():
    return 'hello','python'

print(fun2())
输出结果:
('hello', 'python')

# 不能严格按照函数结构写
# 定义函数
def fun(num):
    odd=[] # 存奇数
    even=[] # 存偶数
    for i in num:
        if i%2:     # 奇数为1,布尔值为True
            odd.append(i)
        else:
            even.append(i)
    return odd,even
lst=[10,55,88,98,78,56,69,33]
print(fun(lst))
输出结果:
([55, 69, 33], [10, 88, 98, 78, 56])
17.4函数的参数定义

默认值参数:

''' 
函数定义默认值参数:函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
'''

def funn(a,b=10):
    print(a,b)

funn(100)	# 只传一个参数,b采用默认值
funn(10,20)   # 20将默认值替换
输出结果:
100 10
10 20

个数可变的位置参数:

定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数;使用*定义个数可变的位置形参;结果为一个元组

def fun(*args):   # 只能是一个参数,args是一个自定义参数
    print(args)

fun(10)
fun(10,20)
fun(10,30,50)
输出结果:
(10,)
(10, 20)
(10, 30, 50)

个数可变的关键字形参:

定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参;使用**定义个数可变的关键字形参;结果为一个字典

def fun(**args):  # 只能是一个参数
    print(args)

fun(a=10)
fun(a=10,b=20)
fun(a=10,b=30,c=50)
输出结果:
{'a': 10}
{'a': 10, 'b': 20}
{'a': 10, 'b': 30, 'c': 50}

在一个函数定义过程中,既有个数可变关键字形参,也有个数可变位置形参,个数可变的位置形参就在个数可变的关键字形参之前!这样就不会报错;

函数的参数总结

函数调用时的参数传递:

'''函数调用时的参数--位置/关键字实参'''
# 将列表中的元素都转换为位置实参--使用*
def fun(a,b,c):  # a,b,c在函数的定义处,所以是形式参数
    print('a=',a)
    print('b=',b)
    print('c=',c)

fun(10,20,30)  # 函数调用时的参数传递,称为位置传参
lst=[50,70,10]
fun(*lst)  # 在函数调用时将列表中的每一个元素都转换为位置实参传入
输出结果:
a= 10
b= 20
c= 30
a= 50
b= 70
c= 10

# 将字典中的每个键值对都关键字实参--使用**
fun(a=100,b=200,c=300)   # 函数的调用处,关键字传参
dic={'a':111,'b':222,'c':333}
fun(**dic)   # 在函数调用时,将字典的每一个键值对转化为关键字实参传入
输出结果:
a= 100
b= 200
c= 300
a= 111
b= 222
c= 333

函数定义时的参数传递:

def fun3(a,b,c,d):   # *从这个*之后的参数在函数调用只能采用关键字传递   def fun3(a,b,*,c,d)
    print('a',a)
    print('b',b)
    print('c',c)
    print('d',d)

fun3(88,99,111,255)  # 位置传参
fun3(a=45,b=55,c=65,d=85)  # 关键字传参
fun3(10,20,c=40,d=50)  # 前两个是位置实参传递,后两个是关键字实参传递

# 函数定义时参数的形参的顺序问题
def fun4(a,b,*,c,d,**args):
    pass

def fun6(*args,**args2):
    pass

def fun7(a,b=10,*args,**args2):
    pass
输出函数:
a 88
b 99
c 111
d 255
a 45
b 55
c 65
d 85
a 10
b 20
c 40
d 50

17.5变量的作用域

程序代码能访问该变量的区域;

根据变量的有效范围可分为:

局部变量:在函数内定义的并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变为全局变量;

全局变量函数体外定义的变量,可作用于函数体外;

def fun(a,b):
    c=a+b  # c称为局部变量,因为c是函数体内定义的变量,a和b为函数的形参,作用范围也是函数内部,相当于局部变量
    print(c)

# print(a)  报错,a与c超出了局部变量的范围(超出了作用域)
# print(c)

name='样老师' # name的作用范围为内部和外部都可以使用,称为全局变量
print(name)

def fun2():
    print('杨老师')

fun2()

def fun3():
    global age  # 函数内部定义的变量为局部变量,局部变量使用global声明,这个变量就是全局变量
    age=20
    print(age)
fun3()
print(age)

输出结果:
样老师
杨老师
20
20
17.6递归函数

定义:如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数;

组成部分:递归调用与递归终止条件;

调用过程:每递归调用一次函数,都会在站内存分配一个栈针;每执行完一次函数,都会释放相应的空间

优缺点:缺点:占用内存多,效率低下;优点:思路和代码简单

def fun(n):  # 计算阶乘的数
    if n==1:
        return 1
    else:
        return n*fun(n-1)

print(fun(6))
输出结果:720

解释:从上到下递推,从下到上回归(还需理解)
fun(6)          720
  |
6*fun(5)            6*(120)  
  |
6*(5*fun(4))         6*(5*24) 
   |
6*(5*(4*fun(3)))        6*(5*(4*6)) 
   |
6*(5*(4*(3*fun(2))))     6*(5*(4*(3*2)))    
    |
6*(5*(4*(3*(2*fun(1)))))      6*(5*(4*(3*(2*1))))

18 斐波那契数列

def fib(n):  # n代表第几位数
    if n==1:
        return 1
    elif n==2:
        return 1
    else:
        return fib(n-1)+fib(n-2)

print(fib(7))

# 1 1 2 3 5 8 13 ...
# 输出前六位数字
for i in range(1,7):
    print(fib(i))
    
输出结果:
13
1
1
2
3
5
8

补充递归是什么:程序调用自身的编程技巧。

19 对象

19.1两大编程思想

面向过程与面向对象:

面向过程 面向对象
区别 事物比较简单,可以用线性的思维去解决(实际操作思想) 事物比较复杂(宏观),使用简单的线性思维无法解决
共同点 都是解决实际问题的一种思维方式
二者相辅相成,并不是对立的;解决复杂问题,通过面向对象的方式便于我们从宏观上把握事物之间的复杂关系,方便我们分析整个系统;具体到微观操作,仍然使用面向过程方式来处理
19.2类和对象的创建

类是多个类似事物组成的群体的统称,能够判断

1.数据类型:不同的数据类型属于不同的类;使用内置函数查看数据类型type()

2.对象:100、99、520都是int类之下包含的相似的不同个例,这个个例专业术语称为实例或对象

3.类的创建:

class Student: # Student 类名;由一个或多个单词组成,每个单词的首字母大写,其余小写
    pass

# python 中一切皆对象,Student是对象吗?有内存空间吗?
print(id(Student))
print(type(Student))
print(Student)
输出结果:
2800713235104
<class 'type'>
<class '__main__.Student'>

4.类的组成:

class Student: # Student 类名;由一个或多个单词组成,每个单词的首字母大写,其余小写
    native_place='吉林'   # 直接写在类里的变量,称为类属性
    def __init__(self,name,age):  # 初始化变量
        self.name=name    # self.name称为实例属性,进行了一个赋值操作,将局部变量的name的值赋值给实体属性
        self.age=age
    # 定义在类内部称为实例方法:传的是实例对象
    def study(self):
        print('我在实习...')

    # 静态方法
    @staticmethod
    def method():
        print('我使用了staticmethod进行修饰,所以我是静态方法')

    # 类方法
    @classmethod
    def cm(cls):
        print('我是类方法,因为我使用了classmethod进行修饰')
19.3类对象与类属性

1.对象的创建:又称为类的实例化

语法: 实例名=类名( )

例子:

class Student: # Student 类名;由一个或多个单词组成,每个单词的首字母大写,其余小写
    native_place='吉林'   # 直接写在类里的变量,称为类属性
    def __init__(self,name,age):  # 初始化变量
        self.name=name    # self.name称为实例属性,进行了一个赋值操作,将局部变量的name的值赋值给实体属性
        self.age=age
    # 定义在类内部称为实例方法:传的是实例对象
    def study(self):
        print('我在实习...')



# 创建Student类的实例对象
stu=Student('张三',20)   # 实例对象(有类指针),会指向类对象
print(id(stu))    # Student类的实例对象的内存地址
print(type(stu))
print(stu)
输出结果:
1761611947792
<class '__main__.Student'>
<__main__.Student object at 0x0000019A28411F10>

class Student: # Student 类名;由一个或多个单词组成,每个单词的首字母大写,其余小写
    native_place='吉林'   # 直接写在类里的变量,称为类属性
    def __init__(self,name,age):  # 初始化变量
        self.name=name    # self.name称为实例属性,进行了一个赋值操作,将局部变量的name的值赋值给实体属性
        self.age=age
    # 定义在类内部称为实例方法
    def study(self):
        print('我在实习...')


# 创建Student类的实例对象
stu=Student('张三',20)   # 实例对象(有类指针),会指向类对象调用类对象
stu.study()   # 对象名.方法名   实例方法
print(stu.name)  # 实例属性
print(stu.age)

# 类名.方法名(类的对象)--实际上就是方法定义处的self
Student.study(stu)   # 与stu.study()功能相同,都是调用student的study方法
输出结果:
我在实习...
张三
20
我在实习...
19.4类方法与静态方法

遗留:两者区别!

class Student: # Student 类名;由一个或多个单词组成,每个单词的首字母大写,其余小写
    native_place='吉林'   # 直接写在类里的变量,称为类属性(类中方法外的变量称为类属性,被该类的所有对象所共享)
    def __init__(self,name,age):  # 初始化变量
        self.name=name    # self.name称为实例属性,进行了一个赋值操作,将局部变量的name的值赋值给实体属性
        self.age=age
    # 定义在类内部称为实例方法
    def study(self):
        print('我在实习...')

stu = Student('张三',40)
stu1 = Student('李四',35)
print(stu.native_place)
print(stu1.native_place)
Student.native_place = '北京'
print(stu.native_place)
print(stu1.native_place)
输出结果:
吉林
吉林
北京
北京

类方法:

使用@classmethod修饰的方法,使用类名直接访问

class Student: # Student 类名;由一个或多个单词组成,每个单词的首字母大写,其余小写
    native_place='吉林'   # 直接写在类里的变量,称为类属性
    def __init__(self,name,age):  # 初始化变量
        self.name=name    # self.name称为实例属性,进行了一个赋值操作,将局部变量的name的值赋值给实体属性
        self.age=age
    # 定义在类内部称为实例方法
    def study(self):
        print('我在实习...')

    @classmethod
    def cm(cls):
        print('我是类方法,因为我使用了classmethod修饰')

Student.cm()
输出结果:
我是类方法,因为我使用了classmethod修饰

静态方法:

使用@staticmethod修饰的方法,使用类名直接访问

class Student: # Student 类名;由一个或多个单词组成,每个单词的首字母大写,其余小写
    native_place='吉林'   # 直接写在类里的变量,称为类属性
    def __init__(self,name,age):  # 初始化变量
        self.name=name    # self.name称为实例属性,进行了一个赋值操作,将局部变量的name的值赋值给实体属性
        self.age=age
    # 定义在类内部称为实例方法
    def study(self):
        print('我在实习...')

    @staticmethod
    def stamen():
        print('我是静态方法,因为我使用了staticmenthod')

Student.stamen()
输出结果:
我是静态方法,因为我使用了staticmenthod
19.5动态绑定属性和方法

Python是动态语言,在创建对象之后可以动态的绑定属性和方法

class Student():
    def __init__(self,name,age):
        self.name = name    # 实例化变量=局部变量
        self.age = age
    def eat(self):
        print('在吃饭')

stu1 = Student('张三',20)
stu2 = Student('马武',47)
# 动态绑定属性
stu2.gender = '女'
print(stu1.name,stu1.age)
print(stu2.name,stu2.age,stu2.gender)

# 动态绑定方法
def show():   # 函数
    print('动态绑定方法')

stu1.show = show    # 方法
stu1.show()


输出结果:
张三 20
马武 47 女
动态绑定方法

python类函数有self和没self的区别:有self必须创建实例;没有self可以直接用类名调用函数。

image-20220416231159592

19.6面向对象的三大特征

封装:提高程序的安全性;

​ 将数据(属性)和行为(方法)包装在类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。

​ 在python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个“_”

class Car():
    def __init__(self,brand):    # brand 是类的一个属性
        self.brand = brand
    def start(self):
        print('汽车已启动')

car = Car('大众')
Car.start(car)    # car.start()
print(car.brand)
输出结果:
汽车已启动
大众
class Student():
    def __init__(self,name,age):
        self.name = name
        self.__age = age  # 不希望在类的外部调用

    def show(self):
        print(self.name,self.__age)

stu = Student('lisi',20)
stu.show()
print(stu.name)
# print(stu.__age)  出错不能调用
print(dir(stu))
print(stu._Student__age)

输出结果:
lisi 20
lisi
['_Student__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'show']
20

继承:提高代码的复用性

语法格式:
class 子类类名(父类1,父类2,...):
	pass

#如果一个类没有继承任何类,则默认继承object
#python支持多继承
#定义子类时,必须在其构造函数中调用父类的构造函数
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,stunum):
        super().__init__(name,age)   # super函数是用来调用父类(超类)的一个方法;
        self.stunum=stunum

class Teacher(Person):
    def __init__(self,name,age,teachyear):
        super().__init__(name,age)
        self.teachyear=teachyear

student=Student('李四',23,'18010832')
teacher=Teacher('么妹',60,23)

student.info()
teacher.info()

输出结果:
李四 23
幺妹 23
class A(object):
    pass

class B(object):
    pass

class C(A,B):
    pass

方法重写:

如果子类对继承的父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写;

子类重写后的方法:super().xxx()调用父类中被重写的方法;

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,stunum):
        super().__init__(name,age)
        self.stunum=stunum
    def info(self):
        super().info()
        print(self.stunum)

class Teacher(Person):
    def __init__(self,name,age,teachyear):
        super().__init__(name,age)
        self.teachyear=teachyear
    def info(self):
        super().info()
        print(self.teachyear)

student=Student('李四',23,'18010832')
teacher=Teacher('么妹',60,23)

student.info()
teacher.info()
输出结果:
李四 23
18010832
么妹 60
23

object类

是所有类的父类,因此所有类都有object类的属性和方法;

内置函数dir()可以查看指定对象所有的属性;

object有一个____str____()方法,用于返回一个对于“对象的描述”对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对____str____()进行重写.

class Student():
    pass

stu=Student()
print(dir(stu))
print(stu)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
<__main__.Student object at 0x00000186A9217400> 返回对象的描述

重写____str____()方法

class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def __str__(self):
        return '我的名字叫{0},今年{1}岁'.format(self.name,self.age)

stu=Person("马丽荣",23)
print(dir(stu))   #可以查看指定对象所有属性
print(type(stu))
print(stu)
输出结果:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
<class '__main__.Person'>
我的名字叫马丽荣,今年23岁

多态:提高程序的可扩展性和可维护性

即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象类型,动态调用哪个对象中的方法

class Anmial(object):
    def eat(self):
        print("动物要吃...")

class Dog(Anmial):
    def eat(self):
        print("狗吃骨头...")

class Cat(Anmial):
    def eat(self):
        print("猫猫爱吃鱼...")

class Person(object):
    def eat(self):
        print("人吃五谷杂粮...")

def func(anmi):
    anmi.eat()  # 不关心对象的类型,只关系该对象是否具有eat的行为

func(Dog())
func(Cat())
func(Person())
func(Anmial())

输出结果:
狗吃骨头...
猫猫爱吃鱼...
人吃五谷杂粮...
动物要吃...

person不存在继承关系,但是有eat方法;

python是动态语言,可以动态的绑定属性和方法,不需要关心person是谁的子类,关心person是否有eat属性或方法;

19.7特殊属性和特殊方法

特殊属性:dict() 获得类对象或实例对象所绑定的所有属性和方法的字典

class A:
    pass
class B:
    pass

class C(A,B):
    def __init__(self,name,age):
        self.name=name
        self.age=age

class D(A):
    pass

#创建C类对象
x=C('Jack',20)  # x是C类型的实例对象;
print(x.__dict__)  #实例对象的属性字典
print(C.__dict__)
print(x.__class__)   # 输出对象所属的类
print(C.__bases__)  # C类的父类类型的元素
print(C.__base__)  # 类的基类
print(C.__mro__)    # 类的层次结构
print(A.__subclasses__())

输出结果:
{'name': 'Jack', 'age': 20}
{'__module__': '__main__', '__init__': <function C.__init__ at 0x000002450577D670>, '__doc__': None}
<class '__main__.C'>
(<class '__main__.A'>, <class '__main__.B'>)
<class '__main__.A'>
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
[<class '__main__.C'>, <class '__main__.D'>]
__init__   __new__ 方法:

class Students(object):
    def __new__(cls, *args, **kwargs):   # 用于创建对象
        print('__new__被调用执行了,cls的id值为:{0}'.format(id(cls)))  # 4608
        objj=super().__new__(cls)
        print('创建的对象的id为:{0}'.format(id(objj)))  # 3824
        return objj

    def __init__(self,name,age):   # 对创建的对象进行初始化
        print('__init__方法调用了id:{0}'.format(id(self)))  # 3824
        self.name = name
        self.age = age

print("输出Student类的的id:{0}".format(id(Students)))  # 4608
print("输出object对象的id:{0}".format(id(object)))   # 2336

stu = Students("张三",20)
print("输出实例对象stuid:{0}".format(id(stu)))  # 3824
image-20220416170741364

cls是类方法里面的第一个参数,表示类本身;self是实例方法里的第一个参数,表示对象本身。

19.8 类的浅拷贝与深拷贝

变量的赋值操作:只是形成了两个变量,实际上还是指向同一个对象

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))
print(cpu2,id(cpu2))

输出结果:
<__main__.CPU object at 0x000001F0FA767400> 2134505845760
<__main__.CPU object at 0x000001F0FA767400> 2134505845760

浅拷贝:python拷贝一般都是浅拷贝,拷贝时对象包含的子对象不拷贝,因此,原对象与拷贝对象会引用同一个子对象。(是重新建立了一个Computer实例对象,相当于原来的实例对象id变了,但是value不变,因此新拷贝出来的computer实例对象cpu和disk还是原来的)

class CPU:
    pass

class Disk:
    pass

class Computer:
    def __init__(self,cpu,disk):
        self.cpu = cpu
        self.disk  =disk

cpu1 = CPU()
# 类的浅拷贝
disk = Disk()
computer = Computer(cpu1,disk)

import copy
computer2 = copy.copy(computer)
print(computer,computer.cpu,computer.disk)
print(computer2,computer2.cpu,computer2.disk)

输出结果:
<__main__.Computer object at 0x0000019CA5AB4640> <__main__.CPU object at 0x0000019CA5AC7400> <__main__.Disk object at 0x0000019CA5B41CA0>
<__main__.Computer object at 0x0000019CA5BBA070> <__main__.CPU object at 0x0000019CA5AC7400> <__main__.Disk object at 0x0000019CA5B41CA0>

深拷贝:使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的的子对象也不相同。

class CPU:
    pass

class Disk:
    pass

class Computer:
    def __init__(self,cpu,disk):
        self.cpu = cpu
        self.disk  =disk

cpu1 = CPU()

disk = Disk()
computer = Computer(cpu1,disk)

import copy
computer3 = copy.deepcopy(computer)
print(computer,computer.cpu,computer.disk)
print(computer3,computer3.cpu,computer3.disk)

输出结果:
<__main__.Computer object at 0x0000021BD3C64640> <__main__.CPU object at 0x0000021BD3C77400> <__main__.Disk object at 0x0000021BD58A1CA0>
<__main__.Computer object at 0x0000021BD591A130> <__main__.CPU object at 0x0000021BD5966D30> <__main__.Disk object at 0x0000021BD5983AC0>

image-20220417134128185

20 模块

20.1 什么是模块__模块化编程的好处

模块:Modules

函数与模块的关系:一个模块中可以包含N多个函数;

在python中一个扩展名为.py的文件就是一个模块;

使用模块的好处:方便其它程序和脚本的导入并使用;避免函数名和变量名冲突;提高代码的可维护性与可重用性。

20.2 模块的导入

创建模块:新建一个.py文件,名称尽量不要与python自带的标准模块名称相同

导入模块:

import 模块名称 [as 别名]

from 模块名称 import 函数/变量/类
import math
print(math.pi)
print(math.pow(2,3))
print(math.ceil(9.001))
print(math.floor(9.999))

输出结果:
3.141592653589793
8.0
10
9
或者这样写...
from math import pi
from math import pow
print(pi)
print(pow(2,3))
输出结果:
3.141592653589793
8.0

导入自定义模块:

新建名为calc.py的模块,写入内容为
def add(a,b):
    return a+b
def div(c,d):
    return (c/d)
    
再新建文件.py,引入自定义的模块
import calc
print(calc.add(2, 3))
print(calc.div(10,4))
输出结果:
5
2.5
也可以这样写:
from calc import add
from calc import div
print(add(2,3))
print(div(10,4))
输出结果:
5
2.5
20.3 以主程序的方式运行

在每个的模块的定义中都包括一个记录模块名称的变量____name____,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其它程序中执行,那么他可能在解释器的顶级模块中执行。顶级模块的____name____变量值为____main____

if __name__ == '__main__':
	pass
# 输入“main”,回车就会输出  if __name__ == '__main__':
新建文件calc2:
def add(a,b):
    return a+b

if __name__ == '__main__':   # 只有当运行calc2的时候才会输出“print”
    print(add(10,24))   
    
再新建另一个文件demo0:
import calc2
print(calc2.add(10,20))   # 不会再输出导入的模块calc2的print...
20.4 python中的包

包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下;

作用:代码规范、避免模块名冲突;

包与目录的区别:包包含init.py文件的目录称为包;目录里通常不包含init.py文件;

Python程序下有多个包,每个包下有与之对应的多个模块,每个模块中就有类,函数属性等...

包的导入:

import 包名.模块名

右键模块:“new package”, "new directory"

image-20220417111207656

右键package1“new python file” --module1.py(写入a=1)与module2.py(写入b=2)

jichu下新建py文件-demo3,在demo3导入包:

import package1.module1
print(package1.module1.a) 

或者可以这样写
import package1.module1 as KK  # KK是package1.module1的别名
print(KK.a)

输出结果:
1

导入包的模块时注意事项:

使用import导入时只能跟包名或模块名
import module
import package

使用from ... import导入时可以跟包,模块,函数,变量
from package import module1
from package.module import a

20.5 python中常见的内置模块
模块名 描述
sys 与python解释器及其环境操作相关的标准库
time 提供与时间相关的各种函数的标准库
os 提供了访问操作系统服务功能的标准库
calender 提供了与日期相关的各种函数的标准库
urllib 用于读取来自网上的(服务器)的数据标准库
json 用于使用JSON序列化和返序列化对象
re 用于在字符串中执行正则表达式匹配和替换
math 提供标准算数运算函数的标准库
decimal 用于进行精确控制运算精度、有效数位和四舍五入操作的的十进制运算
logging 提供了灵活的记录事件、错误、警告和调试信息等日志的信息功能。

补充一个me不知道的知识点:json文件是存储数据结构和对象的文件,在web应用程序中进行数据交换。

 # 获取对象的内存大小
import sys
print(sys.getsizeof(24))
print(sys.getsizeof(str))
# 获取时间
import time
print(time.time())   # 输出为秒
print(time.localtime(time.time())) # 转为本地时间
输出结果:
1650168268.3991244
time.struct_time(tm_year=2022, tm_mon=4, tm_mday=17, tm_hour=12, tm_min=4, tm_sec=28, tm_wday=6, tm_yday=107, tm_isdst=0)
# 读取百度
import urllib.request
print(urllib.request.urlopen('http://www.baidu.com').read())

20.6 第三方模块的安装与使用

第三方模块的在线安装:

pip install schedule

C:\Users>python
>>> import schedule # 无回显表示安装成功

第三方模块的使用:

import 模块名		
import schedule
import time

def job():
    print('哈哈,嘻嘻...')

schedule.every(3).seconds.do(job)

while True:  # 无线循环语句
    schedule.run_pending()
    time.sleep(1)

补充作业:自动化发送信息(qq,wx,mail)怎末写!!??

20.7 编码格式的介绍

常见的字符编码格式:

python的解释器使用的是Unicode(内存);

.py文件在磁盘上使用的是UTF-8(外存)

image-20220417152947148

不同的编码格式决定占用的磁盘空间大小。

更改编码格式:

#encoding=gbk
20.8 文件读写的原理__读取磁盘文件中的内容

文件的读写操作俗称“IO操作”;

文件读写操作流程:

image-20220417160235431

操作原理:

image-20220417160445103

.py文件是由解释器去执行,解释器调用操作系统资源操作磁盘上的文件,对硬盘上的文件进行读和写的操作。打开一个python文件后,应用程序的数据运行在内存中,从内存中拿取数据到应用程序叫读,向内存中输出数据叫做写。

内置函数open()创建文件对象

image-20220417161958890

语法规则:

file = open(filename [,mode,encoding])
被创建的文件对象   要创建或打开的文件名称    打开模式默认为只读  默认文本文件txt中字符的编码格式为gbk;
image-20220417162418399
新建文本文档wendang.txt(默认编码格式是gbk):
中国
美丽
新建.py文件:
file=open('wenben.txt','r',encoding='utf-8')  # 将txt的编码格式转换为.py文件默认的编码格式utf-8
print(file.readlines())
file.close()
输出结果: # 列表形式输出
['中国\n', '美丽']
20.9 常用的文件打开模式

文件的类型:按文件中数据的组织形式,文件分为以下两大类

文本文件:存储的是普通的“字符文本”,默认为Unicode字符集,可以使用记事本程序打开;

二进制文件:把数据内容用“字节”存储,无法用记事本打开,必须使用专用的软件打开,举例:MP3音频文件 .jpg图片 .doc文档等。

# r
file=open('123.txt','w')  # 有该文件写入内容覆盖,没有该文件则创建文件写入内容
file.write('python')
file.close()

输出结果:
有该文件且文件内容为什么都会被写入的内容覆盖掉;
没有该文件则会有新的文件123.txt创建,写入内容
python
#a
file=open('123.txt','a') # 追加内容
file.write('python')
file.close()
在已有的123.tex文件中输出结果:
pythonpython

src_file=open('photo.jpg','rb')
targt_file=open('copyphoto.jpg','wb')

targt_file.write(src_file.read())

src_file.close()
targt_file.close()
打开模式 描述
r 以只读模式打开文件,文件的指针将会放在文件的开头
w 以只写模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头
a 以追加模式打开文件,如果文件不存在则创建,如果文件存在,则在文件末尾追加内容,文件指针在源文件末尾
b 以二进制文件打开文件,不能单独使用,需要与共它模式一起使用,rb,或者wb
+ 以读写方式打开文件,不能单独使用,需要与其它模式一起使用,a+
20.10 文件对象的常用方法
方法名 说明
read([size]) 从文件中读取size个字节或字符的内容返回。若省略[size]则读取到文件末尾,即一次读取文件所有内容;注意一点的是:read会在控制器上输出。
readline() 从文本文件中读取一行内容
readlines() 把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回
write(str) 将字符串内容写入文件
writelines(s_list) 将字符串s_list写入文本文件,不添加换行符
seek(offset[,whence]) 把文件指针移动到新的位置,offset表示相对于whence的位置:offset:为正往结束方向移动,为负往开始方向移动。whence不同的值代表不同的而含义:0,从文件开头计算(默认值);1,从当前位置开始算;2,从文件尾开始算
tell() 返回文件指定的当前位置
flush() 把缓冲区的内容写入文件,但不关闭文件
close() 把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关的资源。
a.txt内容为
中国
美丽
读:
file = open('a.txt', 'r', encoding='UTF-8') 
print(file.read())
输出结果:
中国
美丽

file = open('a.txt', 'r', encoding='UTF-8')
print(file.read(2))
输出结果:
中国

file = open('a.txt', 'r', encoding='UTF-8')
print(file.readline())
输出结果:
中国

file = open('a.txt', 'r', encoding='UTF-8')
print(file.readlines())
输出结果:
['中国\n', '美丽']

写:
file = open('c.txt', 'a')
file.write('hello') # 将字符串写入内容
file.close() # 创建名为c.txt文件内容为“hello”

file = open('c.txt', 'a')
lst = ['java','go','python']
file.writelines(lst)
file.close()  # c.txt文件中内容为 “hellojavagopython”

file = open('d.txt', 'r',encoding='utf-8')
file.seek(3) # 一个中文占2个字节,光标停在“中之前”
print(file.read())
file.close()
输出结果:
国
美丽

file = open('d.txt', 'r',encoding='utf-8')
print(file.read())
print(file.tell())  # 14字节
file.close()
输出结果:
中国
美丽
14

file = open('f.txt', 'a')
file.write('enheng')
file.flush()  # 数据是会先写在缓存里的
file.write('aha')
file.close()
输出结果:
enhengaha
20.11 with语句(上下文管理器)

with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭,以此来达到释放资源的目的。

with open('f.txt','r',encoding='utf-8') as file:
    print(file.read())
    
open('f.txt','r',encoding='utf-8')称为上下文表达式,对象称为上下文管理器
image-20220417184336604

上下文管理器:一个类对象实现了特殊方法____enter____与____exit____,那么称类对象遵守上下文关系协议,而这个类的实例对象就称为上下文管理器。

语言解释:

class MyContentMgr(object):
    def __enter__(self):
        print("__enter__方法被调用了")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("__exit__被调用执行了")

    def show(self):
        print('show方法被调用执行了')

with MyContentMgr() as file: # 相当于MycontentMgr=file
    file.show()
    
输出结果:
__enter__方法被调用了
show方法被调用执行了
__exit__被调用执行了

不管有无异常还是会调用exit方法退出 叫做自动关闭资源

建议用with语句写打开文件

with open('789.jpg', 'rb') as src_file:
    with open('9810.jpg','wb') as targ_file:
        targ_file.write(src_file.read())
20.12 os模块的常用函数

目录操作:os模块是python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样。os模块与os.path模块用于对目录或文件进行操作。

import os
os.system('notepad.exe') # 打开记事本应用程序
os.system('calc.exe') # 打开计算机应运程序

# 直接调用可执行文件
os.startfile('C:\\Program Files (x86)\\Tencent\\QQ\\Bin\\qq.exe') # 登录应用程序qq

os模块操作目录相关函数:

函数 说明
getcwd() 返回当前的工作(文件.py)目录
listdir(path) 返回指定路径下的文件 和目录信息
mkdir(path[,mode]) 创建目录
makedirs(path1/path2...[,mode]) 创建多级目录
rmdir(path) 删除目录
removedirs(path1/path2) 删除多级目录
chdir(path) 将path设置为当前工作目录
import os
print(os.getcwd())

lis = os.listdir('../jichu')  # 注意是“/”
print(lis)
os.mkdir('newpy')  # 默认目录路径与当前写的程序的文件在一个路径下

os.makedirs('A/B/C')

os.rmdir('newpy.py')

os.removedirs('A/B/C')


import os
print(os.getcwd())
os.chdir('E:\\(network)\\python资料及练习\\python学习-练习\\project')
print(os.getcwd())

输出结果:
E:\(network)\python资料及练习\python学习-练习\jichu
E:\(network)\python资料及练习\python学习-练习\project

20.13 os.path模块的常用方法
函数 说明
abspath(path) 用于获取文件或目录的绝对路径
exists(path) 用于判断文件或目录是否存在,如果存在返回True,否则返回False
join(path,name) 将目录与目录或者文件名拼接起来
splitext() 分离文件名和扩展名
basename(path) 从一个目录中提取文件名
split() 目录与文件拆分
dirname(path) 从一个路径中提取文件路径,不包括文件名
isdir(path) 用于判断是否为路径
import os.path
print(os.path.abspath('project'))  # 目录的绝对路径
print(os.path.exists('jichu'),os.path.exists('calc.py'))
print(os.path.join('E:\\Python','demo110.py'))
print(os.path.split('E:\(network)\python资料及练习\python学习-练习\jichu'))  #目录与文件拆分
print(os.path.splitext('bug.py'))
print(os.path.basename('E:\(network)\python资料及练习\python学习-练习\jichu\leiyuduixiang.py'))
print(os.path.dirname('E:\(network)\python资料及练习\python学习-练习\jichu\leiyuduixiang.pyd'))
print(os.path.isdir('E:\(network)\python资料及练习\python学习-练习\jichu'))

输出结果:
E:\(network)\python资料及练习\python学习-练习\project
True False
E:\Python\demo110.py
('E:\\(network)\\python资料及练习\\python学习-练习', 'jichu') 
('bug', '.py')
leiyuduixiang.py
E:\(network)\python资料及练习\python学习-练习\jichu
True

练习:获取当前目录下的所有.pyw文件

import os
path = os.getcwd()
pyfile = os.listdir(path)
for file in pyfile:
    if file.endswith('.py'):  # 以什么结尾
        print(file)

walk()方法:递归遍历指定目录下所有的文件和目录。而且将目录下的子目录都遍历出来。

image-20220418004304630
import os
path = os.getcwd()
lis_files = os.walk(path) # 返回为一个元组
print(lis_files)  # 是一个迭代器对象 <generator object walk at 0x00000148F96ED7B0>
for dirpath,dirname,filename in lis_files:
    print(dirpath)
    print(filename)
    print(dirname)
    print('------------------')  # 不仅遍历出当前目录、文件,还遍历出子目录与子文件
    
输出结果:
<generator object walk at 0x00000134139F3740>
E:\(network)\python资料及练习\python学习-练习\jichu
['123.txt', '789.jpg', '9810.jpg', 'a.txt', 'bug.py', 'c.txt', 'calc.py', 'copyphoto.jpg', 'd.txt', 'demo19.py', 'demo3.py', 'f.txt', 'leiyuduixiang.py', 'Object类.py', 'os模块.py', 'os模块函数.py', 'with语句复制图片.py', '上下文管理器.py', '主程序1.py', '主程序2.py', '内置模块.py', '在线安装三方模块使用.py', '多态.py', '引入自定义模块.py', '斐波那契数列.py', '模块.py', '深拷贝与浅拷贝.py', '特殊方法.py', '特殊方法2.py', '生活照10.jpg', '类方法与静态方法.py', '继承.py', '获取.py文件.py', '试试.py', '读写方法.py', '读取文件.py', '调试.py']
['directory1', 'me', 'newpy', 'package1', '__pycache__']
------------------
E:\(network)\python资料及练习\python学习-练习\jichu\directory1
['1.py', '2.py']
['subdir2']
------------------
E:\(network)\python资料及练习\python学习-练习\jichu\directory1\subdir2
['su1.py']
[]
------------------
E:\(network)\python资料及练习\python学习-练习\jichu\me
[]
['mine']
------------------
E:\(network)\python资料及练习\python学习-练习\jichu\me\mine
[]
['you']
------------------
E:\(network)\python资料及练习\python学习-练习\jichu\me\mine\you
[]
[]
------------------
E:\(network)\python资料及练习\python学习-练习\jichu\newpy
[]
[]
------------------
E:\(network)\python资料及练习\python学习-练习\jichu\package1
['module1.py', 'module2.py', '__init__.py']
['__pycache__']
------------------
E:\(network)\python资料及练习\python学习-练习\jichu\package1\__pycache__
['module1.cpython-38.pyc', '__init__.cpython-38.pyc']
[]
------------------
E:\(network)\python资料及练习\python学习-练习\jichu\__pycache__
['calc.cpython-38.pyc', '主程序1.cpython-38.pyc']
[]
------------------
import os
path = os.getcwd()
lis_files = os.walk(path) # 返回为一个元组
print(lis_files)  # 是一个迭代器对象 <generator object walk at 0x00000148F96ED7B0>
for dirpath,dirname,filename in lis_files:
    for dir in dirname:
        print(os.path.join(dirpath,dir)) # 当前目录下有多少个子目录

    for file in filename:
        print(os.path.join(dirpath,file))  # 遍历指定目录下所有的文件以及目录类似于递归的操作
    print('--------------------')
    
输出结果:
<generator object walk at 0x0000024AD0933740>
E:\(network)\python资料及练习\python学习-练习\jichu\directory1
E:\(network)\python资料及练习\python学习-练习\jichu\me
E:\(network)\python资料及练习\python学习-练习\jichu\newpy
E:\(network)\python资料及练习\python学习-练习\jichu\package1
E:\(network)\python资料及练习\python学习-练习\jichu\__pycache__
E:\(network)\python资料及练习\python学习-练习\jichu\123.txt
E:\(network)\python资料及练习\python学习-练习\jichu\789.jpg
E:\(network)\python资料及练习\python学习-练习\jichu\9810.jpg
E:\(network)\python资料及练习\python学习-练习\jichu\a.txt
E:\(network)\python资料及练习\python学习-练习\jichu\bug.py
E:\(network)\python资料及练习\python学习-练习\jichu\c.txt
E:\(network)\python资料及练习\python学习-练习\jichu\calc.py
E:\(network)\python资料及练习\python学习-练习\jichu\copyphoto.jpg
E:\(network)\python资料及练习\python学习-练习\jichu\d.txt
E:\(network)\python资料及练习\python学习-练习\jichu\demo19.py
E:\(network)\python资料及练习\python学习-练习\jichu\demo3.py
E:\(network)\python资料及练习\python学习-练习\jichu\f.txt
E:\(network)\python资料及练习\python学习-练习\jichu\leiyuduixiang.py
E:\(network)\python资料及练习\python学习-练习\jichu\Object类.py
E:\(network)\python资料及练习\python学习-练习\jichu\os模块.py
E:\(network)\python资料及练习\python学习-练习\jichu\os模块函数.py
E:\(network)\python资料及练习\python学习-练习\jichu\with语句复制图片.py
E:\(network)\python资料及练习\python学习-练习\jichu\上下文管理器.py
E:\(network)\python资料及练习\python学习-练习\jichu\主程序1.py
E:\(network)\python资料及练习\python学习-练习\jichu\主程序2.py
E:\(network)\python资料及练习\python学习-练习\jichu\内置模块.py
E:\(network)\python资料及练习\python学习-练习\jichu\在线安装三方模块使用.py
E:\(network)\python资料及练习\python学习-练习\jichu\多态.py
E:\(network)\python资料及练习\python学习-练习\jichu\引入自定义模块.py
E:\(network)\python资料及练习\python学习-练习\jichu\斐波那契数列.py
E:\(network)\python资料及练习\python学习-练习\jichu\模块.py
E:\(network)\python资料及练习\python学习-练习\jichu\深拷贝与浅拷贝.py
E:\(network)\python资料及练习\python学习-练习\jichu\特殊方法.py
E:\(network)\python资料及练习\python学习-练习\jichu\特殊方法2.py
E:\(network)\python资料及练习\python学习-练习\jichu\生活照10.jpg
E:\(network)\python资料及练习\python学习-练习\jichu\类方法与静态方法.py
E:\(network)\python资料及练习\python学习-练习\jichu\继承.py
E:\(network)\python资料及练习\python学习-练习\jichu\获取.py文件.py
E:\(network)\python资料及练习\python学习-练习\jichu\试试.py
E:\(network)\python资料及练习\python学习-练习\jichu\读写方法.py
E:\(network)\python资料及练习\python学习-练习\jichu\读取文件.py
E:\(network)\python资料及练习\python学习-练习\jichu\调试.py
--------------------
E:\(network)\python资料及练习\python学习-练习\jichu\directory1\subdir2
E:\(network)\python资料及练习\python学习-练习\jichu\directory1\1.py
E:\(network)\python资料及练习\python学习-练习\jichu\directory1\2.py
--------------------
E:\(network)\python资料及练习\python学习-练习\jichu\directory1\subdir2\su1.py
--------------------
E:\(network)\python资料及练习\python学习-练习\jichu\me\mine
--------------------
E:\(network)\python资料及练习\python学习-练习\jichu\me\mine\you
--------------------
--------------------
--------------------
E:\(network)\python资料及练习\python学习-练习\jichu\package1\__pycache__
E:\(network)\python资料及练习\python学习-练习\jichu\package1\module1.py
E:\(network)\python资料及练习\python学习-练习\jichu\package1\module2.py
E:\(network)\python资料及练习\python学习-练习\jichu\package1\__init__.py
--------------------
E:\(network)\python资料及练习\python学习-练习\jichu\package1\__pycache__\module1.cpython-38.pyc
E:\(network)\python资料及练习\python学习-练习\jichu\package1\__pycache__\__init__.cpython-38.pyc
--------------------
E:\(network)\python资料及练习\python学习-练习\jichu\__pycache__\calc.cpython-38.pyc
E:\(network)\python资料及练习\python学习-练习\jichu\__pycache__\主程序1.cpython-38.pyc
--------------------

image-20220418011504072

补充词语理解:

循环(loop),指的是在满足条件的情况下,重复执行同一段代码。比如,while语句。

迭代(iterate),指的是按照某种顺序逐个访问列表中的每一项。比如,for语句。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。走n遍,反反复复

遍历(traversal),指的是按照一定的规则访问树形结构中的每个节点,而且每个节点都只访问一次。'走一遍'

递归(recursion),指的是一个函数不断调用自身的行为。比如,以编程方式输出著名的斐波纳契数列。

21 BUG

21.1 bug常见错误

1.漏了末尾的冒号,如if语句,循环语句,else子句等;

2.缩进错误;

3.把英文符号写成中文符号;

4.字符串拼接的时候,把字符串和数字拼在一起;

5.没有定义变量;

6."=="比较运算符与赋值运算符"="混用

思路不清导致的问题解决方案

1.使用print()函数;

2.使用"#"暂时注释部分代码;

21.2 bug的常见类型

被动掉坑:程序代码逻辑没有错,只是因为用户错误操作或者一些"例外情况"而导致的程序崩溃;

异常处理机制:可以在异常出现时即时捕获,然后内部继续"消化",让程序继续运行;

image-20220427164550258

try...except...结构

try:
	...
	可能会出现的异常的代码...
	...
except   xxx(异常类型):
	...
	异常处理代码...    # 报错后执行的代码
	...
# 输入两个整数并进行除数运算
try:
    num1 = int(input('输入第一个整数:'))
    num2 = int(input('输入第二个整数:'))
    num = num1/num2
    print(num)
except:
    print('输出错误')

    或
try:
    num1 = int(input('输入第一个整数:'))
    num2 = int(input('输入第二个整数:'))
    num = num1/num2
    print(num)
except ZeroDivisionError:
    print('输出错误')

多个except结构:捕获异常的顺序按照先子类后父亲类的顺序,为了避免遗漏可能出现的异常,可以在最后增加BaseException

try:
	...
	...   # 可能会出现的异常的代码
	...
except Expection1:
	...
	...   # 异常处理代码
	...
except Expection2:
	...
	...   # 异常处理代码
	...
except BaseException:
	...
	...   # 异常处理代码
	...
try:
    num1 = int(input('输入第一个整数:'))
    num2 = int(input('输入第二个整数:'))
    num = num1/num2
    print(num)
except ZeroDivisionError:
    print('除数不能为0')
except ValueError:
    print('不能为字母')
except BaseException as e:
    print('程序结束')

try...except...else结构

如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块

try:
    num1 = int(input('输入第一个整数:'))
    num2 = int(input('输入第二个整数:'))
    num = num1/num2

except BaseException as e:
    print('出错了')
    print(e)
else:
    print('结果为:',num)
	

try...except...else...finally结构

finally块无论如何是否发生异常都会被执行,能常用来释放try块中申请的资源

image-20220428164930476
try:
    num1 = int(input('输入第一个整数:'))
    num2 = int(input('输入第二个整数:'))
    num = num1/num2
except BaseException as e:
    print('出错了')
    print(e)
else:
    print('结果为:',num)
finally:
    print('无论是否产生异常,总会被执行的代码')
print('程序结束')

输出结果:
输入第一个整数:78
输入第二个整数:2
结果为: 39.0
无论是否产生异常,总会被执行的代码
程序结束
21.2 常见的异常
序号 异常类型 描述
1 ZeroDivisionError 除(或取模)零(所有数据类型)
2 IndexError 序列中没有此索引(index)
3 KeyError 映射中没有这个键
4 NameError 未声明/初始化对象(没有)

22 过程note

22.1 python 内置函数sorted()

sorted()函数对所有可迭代对象进行排序操作。

语法:

sorted(interable,cmp=None,key=None,reverse=False)
interable--可迭代对象;
cmp--比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则是:大于则返回1,小于则返回-1,等于则返回0;
key--主要用来进行比较的元素,只有一个参数,具体的函数参数就是取自可迭代对象中,指定可迭代对象中的一个元素进行排序。
reverse--排序规则,reverse=True降序,reverse=False升序(default).
22.2 sys.argv[]

一个从程序外部获取获取参数的桥梁,获得的是一个列表,用[]提取其中的元素,其第一个元素是程序本身,随后才依次是外部给予的参数。

模块:a_plus_b.py
def plus(a:int, b:int ) -> int:
	return a + b
模块:main.py
import sys
from a_plus_b import plus
a = int(sys.argv[1])
b = int(sys.argv[2])
print(plus(a,b))
22.3 内置函数sum()
  • sum()方法对序列进行求和计算;
sum(interable[,start])
interable--可迭代对象,列表、元组、集合。
start--指定相加的参数,如果没有设定这个值,默认为0.
22.4 内置函数map()
  • map() 会根据提供的函数对指定序列做映射;
map(function,interable,...)
function--函数
interable--一个或多个序列
返回迭代器(python3.x)
import sys

input_filepath = sys.argv[1]
with  open(input_filepath,'r',encoding='utf-8') as sum_file:
sumfile = sum_file.read().split(' ')
# print(sumfile,type(sumfile))
new_num = map(int,sumfile)
print(sum(new_num))
22.5 splitlines()方法
  • splitlines() 按照('\r','\r\n','\n')分隔,返回一个包含各行作为元素的列表,如果参数keepends为False,不包含换行符,如果为True,则保留换行符。
splitlines()方法语法:
str.splitlines([keepends])
22.6 count()方法
  • count()方法用于统计字符串里某个字符或字符串出现的次数,可选参数为在字符串搜索的开始与结束位置。
count()方法语法:
str.count(sub,start = 0,end = len(string))
sub--搜索的子字符串
start--字符串开始搜索的位置。默认为第一个字符,第一个字符的索引值为0。
end--字符串中结束搜索的位置。字符中第一个字符的索引为0。默认为字符串的最后位置
返回值:返回子字符串在字符串中出现的次数。
def num_your(poem):
	# write your code here
    # num_count = 0
    # for item in poem.splitlines():
    #     if 'your' in item:
    #         num_count += 1
    # return num_count
	num_count = poem.count(' your ')
	return num_count
22.7 len()方法(内置函数)
  • len()方法返回对象(字符、列表、元组)长度或项目个数。

    len()方法语法:
    len(s)
    s--对象
    
    返回值:对象长度
    
22.8 内置函数eval()函数
  • eval()函数用来执行一个字符串表达式,并返回表达式的值。

    语法:
    eval(expression[,globals[,locals]])
    expression--表达式
    globals--变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
    
    
22.9 requests.post()定义和用法

post()方法将POST请求发送到指定的URL。

post()方法将某些数据发送到服务器时使用。

  • 语法
requests.post(url, data={key: value}, json={key: value}, args)

args表示下面参数表中的零个或多个*命名*参数。例:

requests.post(url, data = myobj, timeout=2.50)
  • 参数值
参数 描述
url 必须。请求的网址
data 可选。字典,元组列表,字节或要发送到指定URL的文件对象
json 可选。要发送到指定URL的JSON对象
files 可选。要发送到指定URL的文件字典
allow_redirects 可选。用于启用/禁用重定向的布尔值。 默认True(允许重定向)
auth 可选。用于启用某种HTTP身份验证的元组。 默认None
cert 可选。指定证书文件或密钥的字符串或元组。 默认None
cookies 可选。要发送到指定网址的Cookie字典。 默认None
headers 可选。要发送到指定网址的HTTP标头字典。 默认None
proxies 可选。URL代理协议字典。 默认None
stream 可选。如果响应应立即下载(False)或流式传输(True)的布尔指示。 默认False
timeout 可选。一个数字或一个元组,指示等待客户端建立连接和/或发送响应的秒数。 默认值None表示请求将继续,直到连接关闭
verify 可选。用于验证服务器TLS证书的布尔值或字符串指示。 默认True

标签:__,10,输出,python,基础,笔记,lst,print
来源: https://www.cnblogs.com/9808081314mlr/p/16542217.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有