python基础

发布于:2025-03-16 ⋅ 阅读:(18) ⋅ 点赞:(0)

目录

程序设计语言

机器语言:

一种二进制语言,它直接使用二进制代码表达指令,是计算机硬件可以直接识别和执行的程序设计语言

汇编语言:

使用方便记忆符与机器语言中的指令–对应

高级语言:

是接近自然语言的一种计算机程序设计语言,python、java都是高级语言

编程语言的分类:

  • 编译型
  • 解释型

编译型:是指将源代码转换成目标代码的过程,通常源代码是高级语言代码,目标代码是机器语言代码,执行编译的计算机程序称为编译器(compiler)

解释型:是指将源代码逐条转换成目标代码同时逐条进行目标代码的过程,执行解释的计算机程序称之为解释器(interpreter)

print用法

print(输出内容)
print()函数的完整的语法格式
print(value,...,sep='',end='\n',file=None)
print('hello world!!!')     #编写程序
a=100  
b=50
print("欢迎大家!",'bbbbb','aaaaaa',a,b,a+b)
  • 写入文件
fp=open('note.txt','w')   #打开文件w是写的意思
print('你好啊!',file=fp)     #将北京欢迎你输出到note.txt文件中
fp.close()  #关闭文件
  • 使用连接符,连接字符串
print("北京",end="-->")
print("欢迎你!")       #没有修改end符号,所以print结束之后有一个换行
print("北京欢迎你"+'2025')        #打印结果为北京欢迎你2025,没有换行

input用法

语法结构:
x=input('提示文字')        #无论输入的数据是什么,都是字符串类型

a=input('请输入你的名字:')
print(a)        #输入名字并且输出

注释:

程序员在代码中对代码功能解释说明的标注性文字可以调高代码的可读性
注释的内容被python解释器忽略,不被计算机执行单行注释,多行注释和中文声明注释。

代码缩进:

是指每行语句开始前的空白区域,用来表示python程序间 的包含和层次关系
类定义,函数定义,流程控制语句,以及异常处理语句等行尾 的冒号和下一行的缩进表示一个代码块的开始,而缩进结束,则表示一个代码块的结束
通常情况下采用个空格作为一个缩进量

python中的数据类型和运算符

保留字和标识符

在python中被赋予一些特定意义的一些单词,在开发程序的时候,不可以把这些保留字作为变量,函数,类,模块和其他对象名称来使用(保留字严格区分大小写)

import keyword
print(keyword.kwlist)        #导入keyword保留字,之后查看保留字列表
print(len(keyword.kwlist))        #统计保留字的个数        #len是python中的内置函数

标识符的命名规则

python标识符可以是字符,数字,下划线,并且第一个字符不能是数字
不能使用python中的保留字
标识符严格区分大小写
以下划线开头的标识符有着特殊的意义,一般应该避免使用相似的标识符,允许使用中文作为标识符,但是不建议使用

标识符的命名规范

模块名尽量短小,并且全部使用小写字母,可以使用下划线分割多个字母。例如:grame_main
包名尽量短小,并且全部使用小写字母,不推荐使用下划线。例如:com.ysjpython,不推荐使用com_ysjpython
类名采用单词首字母大写形式(Pascal风格),例如:MyClass
模块内部的类采用"“+Pascal风格的类名组成,例如在MyClass中的内部_InnerMyClass
函数,类的属性和方法的命名,全部使用小写字母,多个字母之间使用下划线分隔
常量命名时采用全部大写字母,可以使用下划线
使用单下划线”
"开头的模块变阿玲或者函数是受保护的,使用from xxx import *“语句从模块中导入的时候,这些模块变量或者函数不能被导入,使用双下划线”_"开头的实例变量或者方法是类私有的
以双下划线开头和结尾的是python的专用标识,例如:init()表示初始化函数

变量的定义和使用

变量是保存和表示数据的值 的一种语法元素

变量的语法结构:

变量名=value
luck_number=8

a=8
b='a'
print(type(a),type(b))        #使用type来查看数据类型是什么
print(a,b)

在pyhton中允许多个变量指向同一个值

no=number=1023
print(no,number)
print(id(no),id(number))

变量的命名规则:

  • 变量名必须是一个有效的标识符
  • 变量名不能使用python中的保留字
  • 谨慎使用小写字母i和大写字母o
  • 选择有意义的单词作为变量名

基本数据类型

1.整数类型

表示的数字是没有小数部分的数值,包含正整数,负整数和0

2.浮点型

表示带有小数点点数值,由整数部分和小数部分组成
注意事项:两个浮点类型的数在进行运算的时候,有一定的概率运算结果增加一些不确定的尾数
python中的复数与数学中的复数形式完全一致,由实部和虚部组成
pyhton中的实数部分使用.real表示,虚数部分使用.imag表示

print(0.1+0.2)
print(round(0.1+0.2,1))        #round可以定义保留的位数

3.字符串类型

连续的字符序列,可以表示计算机能识别的一切字符
字符串的界定符:单引号,双引号,三引号
原字符:使转移字符失效的字符,r或R

info="""
收件人:韩子
手机号:111
"""
print(info)
三个引号将多个字符串包含,从而输出了多个字符串

字符串又称之为有序的字符序列,对于字符串中,某一个字符的检索,称之为索引
对字符串中某个子串或者区间的检索称之为切片,切片的语法结构: 字符串或者字符串变量[n:m]

s='hello world~'
print(len(s))
print(type(s))
print(s[0],s[-12])      #取索引为0的,反向取索引为-12的
print('北京欢迎你'[-1])
print(s[2:7])           #从2-7不包含7
print(s[-10:-5])        #反向递减
print(s[-2:])           #默认是切到字符串的结尾
print(s[:5])            #默认是从0开始切到4不包含5

4.布尔类型

用来表示真或者假,在python中使用标识符True或者False表示布尔类型的值
True表示整数1,False表示整数0
布尔值为False的情况如下

False或者None
数字中的0,包含0,0.0,虚数0
空序列,包含空字符串、空元祖、空列表、空字典、空集合
自定义对象的实例,该对象的__bool__()方法返回False或者__len__()方法返回0

非0的整数的布尔值全是True
所有非空字符串的布尔值都是True
空字符串的布尔值为False

常用的字符串操作

1.x+y 将字符串x与y连接起来
2.xn或nx 复制n次字符串x
3.x in s 如果x时s的子串,结果为True,否则结果为False

x='2025'
y='新的一年'
print(x+y)          #结果是2025新的一年
print((x+y)*10 )    #将这个内容复制10次
print('北京'in y)    #判断在y中是否存在北京存在就是true否则就是false
print('上海'in y)

数据类型之间的相互转换

int(x) 吧x转换为整数类型
float(x) 把x转换为浮点数类型
str(x) 把x转换成字符串
chr(x) 将整数x转换为一个字符
ord(x) 讲一个字符x转换为其对应的整数值
hex(x) 将一个字符x转换为一个十六进制字符串
oct(x) 将一个整数x转换为一个八进制字符串
bin(x) 将一个整数x转换成一个二进制字符串

x=10
y=3
z=x/y
print(z,type(z))
print(int(3.22222))
c=ord('韩')
print(c)
print(chr(26472))

#进制转换
print('十进制转换为二进制',hex(12345))
print("十进制转换为八进制",oct(12345))
print("十进制转换为二进制",bin(12345))

eval()函数的使用

python中的内置函数
用于去掉字符串最外侧的引号,并且按照python语句方式执行去掉引号后的字符串
eval()函数通常和input()函数一起使用

eval的语法格式

变量=eval(字符串)

hello='北京欢迎你!'
print(hello)                #直接输出
print(type(hello))            #输出类型
print(eval('hello'))            #去掉''输出hallo函数
print(eval('\'北京欢迎你!!\''))        #去掉引号输出北京欢迎你!!

s='3.14+3'
print(s,type(s),int(eval(s)),type(int((eval(s))))

算术运算符

  • // 整除 % 取余
    ** 幂运算 运算符的优先级由高到低 第一级: ** 第二级: *、/、%、// 第三级: +、-

赋值运算符

+= /=
*= %=
**= //=

关系运算符
<
= <=
== !=
逻辑运算符 and(从左到右结合) or(从左到右结合)

not(从右到左结合)

位运算符 & 与运算(全1为1其余为0) | 或运算(全0为0其余为1) ^ 异或运算(全1为0,其余为1) ~
取反运算(1为0,0为1)

左移位(<<) 将一个二进制的数字向左移动指定的位数,左边(高位端)溢出的位数被丢弃,右边(低位端)的空位用0补充

右移位(>>)
是将一个二进制数向右移动指定的位数,右边(低位端)溢出的位卑丢弃,左边(高位端)的空位端,如果最高位是0(正数)左侧空位填0,如果最高位是1(负数),左侧空位填写1.

左乘右除

运算符的优先级

print(1+1)
print(2-1)
print(2*2)
print(4/2)
print(4//2)
print(2**3)

x=20
print(x)            #20
print(type(x))      #int
x+=x
print(x)            #40
print(type(x))      #int
x/=x
print(x)            #1.0
print(type(x))      #float
print(int(x))       #1
print(type(x))      #float 

#链式赋值
a=b=c=100
print(type(float((a+b+c))),a,b,c)
print(a,b,c)

#系列解包赋值
a,b=10,20
print(a,b)

a,b=10,20
a,b=b,a
print(a,b)         #值的交换,将a和b的值交换 a变成20,b变成10

#比较运算符
a=10
b=20
c=a==b
print(c)
print(a<b)

#逻辑运算符的使用
print( False or True)
print(True and False)
print(False and False)
print(True or True)

程序练习:

father_height=eval(input('请输入爸爸的身高:'))
mother_height=eval(input('请输入妈妈的身高:'))
son_height=((father_height+mother_height)*0.54)
print('儿子的身高为:',son_height,'cm')


a=eval(input('请输入一个四位的整数:'))
print('个位数为:',a%10)
print('十位数为:',a//10%10)
print('百位数为:',a//100%10)
print('千位数为:',a//1000%10)

print('-'*40)

num=input('请输入一个四位的整数:')
print('个位上的数字为:',num[3])
print('十位上的数字为:',num[2])
print('百位上的数字为:',num[1])
print('千位上的数字为:',num[0])
print('-'*40)

程序的描述方式

自然语言

Input #输入
Process #处理
Output #输出

顺序结构

按照程序语句的自然顺序,从上到下,依次执行每条语句程序

赋值语句
输入/输出语句
模块导入语句

name=input('请输入您的姓名:')
age=eval(input("请输入您的年龄:"))
print('姓名:',name)
print('年龄:',age)

选择结构

#if语句
c=eval(input('请输入一个数字:'))
if c%2==0:
    print(c,'是偶数')
else:
    print(c,'是奇数')
    
    
num=input('请输入一个数字:')
print('中'if num=='1234567' else '低')



多分支if语句

score=eval(input('请输入您的成绩:'))
if score<0 or score>100:
    print('不合格,请重新输入!')
elif score>=90 and score<=100:
    print('合格')
elif   score>50 and score<=60:
    print('及格')
else:
    print('不及格')
    
if嵌套的使用

多个条件的连接

使用and连接多个条件判断时,只有同时满足多个条件,才能执行if语句

user_name=input('请输入您的用户名:')
pwd=input('请输入您的密码:')
if user_name=='hjm' and pwd=='888':
    print("登陆成功!")
else:
    print("登陆失败")

循环结构

for循环

#遍历字符串
for i in 'hello':
    print(i)

#range函数
for i in range(0,10):        包含0不包含10的整数序列0-9
    print(i)
    
#range函数
for i in range(11):
    if i%2==0:
        print(i,'是偶数')


sum=0
for i in range(0,101):
    sum+=i
print(sum)

三角形
 for i in range(1,6):
    for j in range(1,6-i):
        print(' ',end='')
    for k in range(1,i*2):
        print('*',end='')
    print() 
    

while循环

4步骤:
1)初始化变量
2)条件判断
3)语句块
4)改变变量

程序跳出语句break
跳出循环结构,通常用if一起搭配使用

answer=input("今天需要上课吗?y/n")
while answer=='y':
     print('好好学习天天向上')
     answer = input("今天需要上课吗?y/n")

break使用

使用for循环
for i in range(1,4):
    user_name=input('请输入用户名:')
    pwd=input('请输入密码:')
    if user_name=='hjm' and pwd=='aaa':
        print('系统正在登录,请稍后!')
        break
    else:
        if  i<3:
            print('还有',3-i,'次机会!')
else:
    print('三次均输入失败:!!!')

使用while循环
i=0
while i<3:
    user_name=input('请输入用户名:')
    pwd=input("请输入密码:")
    if user_name=='hjm' and pwd=='aaa':
      print('系统正在登录,请稍后!')
      break
    else:
        if i<2:
            print('用户名或者密码不正确,您还有',2-i,'次机会')
    i+=1
if i==3:
    print('对不起,三次均输入失败,退出程序!')

空语句pass

pass是python中的保留字,在语法结构中只起到站位符的作用,是使语法结构完整,不报错
一般情况可以在if、for、while、函数的定义、类的定义中使用

#9*9 乘法表
for i in range(1,10):
    for j in range(1,i+1):
        print(str(j)+'*'+str(i)+'='+str(i*j),end='\t')
    print()

组合数据类型

序列和索引

索引是一个用于存储多个值的连续空间,每个值都对应一个整数的编号,称之为索引

s='helloworld'
#切片操作:
s1=s[0:5:2] #索引从0开始,到5结束(不包含5)步长为2
print(s1)
#省略开始位置,默认从0开始
s2=s[:5:1]
print(s2)
print(s[:5:1])
#省略开始位置,省略步长
print(s[::])        #默认到结尾序列的最后一个元素(包含最后一个元素)
print(s[5:])
print(s[5::])       #11和12的代码功能相同
print(s[::2])       #获取索引为0 2 4 8 的
#步长为负数
print(s[::-1])
print(s[-1:-11:-1]) #结果是一样的,将helloworld反向输出

序列的相加操作

x in s #如果x时s的元素,结果为True,否则结果为False
for not in s #如果x不是s的元素,结果为True,否则结果为False
len(s) #序列s中的元素的个数(即序列的长度)
mx(s) #序列s中的元素的最大值
min(s) #序列s中元素的最小值
s.index(x) #序列s中第一次出现元素x的位置
s.count(x) #序列s中出现x的总次数

s='helloworld'
a='e' in s               #in的使用!
b='e' not in s           #not in的使用
print('e在helloworld中存在吗?',a)
print('e在helloword中不存在吗?',b)
print('len()',len(s))       #求长度
print('max()',max(s))       #最大值
print('min()',min(s))       #最小值

#序列对象的方法,使用序列的名称去打点调用
print('s.index():',s.index('o'))    #o在s.index第一次出现的索引的位置
print('s.count()',s.count('o'))    #统计o在字符串s中出现的次数

列表类型

是指一系列特定顺序的元素组成.是python中内置的可变序列
在pyhton中使用[]定义列表,元素与元素之间使用英文的逗号分隔
列表中的元素可以是任意的数据类型

列表创建的方法

使用[]直接创建列表
语法结构:
列表名=[element1,element2,…elementN]
使用内置函数list()创建列表
语法结构如下:
列表名=list(序列)

lst=['你好','hello','world',100,98]
print(lst)
lst2=list('helloworld10098')
print(lst2)
lst3=list(range(1,10,2))
print(lst3)                 #从1开始到10结束,步长为2,不包含10
print(lst+lst3+lst2)
print(lst*3)
print(len(lst))
print(lst2.count('o'))      #统计o的个数
print(lst2.index('o'))      #统计o在列表中第一次出现的位置

列表的删除

语法结构如下:
del 列表名

list4=[10,20,30]
print(list4)

del list4        #删除列表

函数的使用:

enumerate函数的使用语法结构

lst=['hello','world','python','php']
for item in lst:        #使用for循环遍历列表
    print(item,end=' ')
print()

#使用for循环和range()函数,len()函数,根据索引进行遍历
for i in range(0,len(lst)):
    print(lst[i],end=' ')
print()

#使用enumerate()函数
for b,item in enumerate(lst):
    print(b,item,end=' ')       #b是序号,不是索引
print()

for b,item in enumerate(lst,start=1):   #使用start指定序号为1,所以从1开始打印
    print(b,item,end=' ')
print()
    
for b,item in enumerate(lst,2):   #不使用start,直接使用数字也可以开始
    print(b,item,end=' ')
print()

列表的相关操作

lst.append(x) 在列表lst最后增加一个元素
lst.insert(index,x) 在列表中第index位置增加一个元素
lst,clear() 清除列表lst中所有元素
lst.pop(index) 将列表lst中第index位置的元素取出来,并且从列表中将其删除
lst.remove(x) 将列表lst中出现的第一个元素x删除 lst.reverse(x) 将列表lst中的元素反转
lst.copy() 拷贝列表lst中的所有元素,生成一个新的列表

test=['hello','world','python']
print('原列表:',test,id(test))     #输出原来列表的内存地址
#增加元素的操作:
test.append('sql')
print('增加元素后:',test,id(test))       #内存地址不变,可是增加了一个sql元素
#插入元素,在指定的索引上插入
test.insert(1,100)      #在索引为1的位置上插入了元素,其他元素后撤
print(test,id(test))
#列表元素的删除
test.remove('world')        #将列表中的world元素删除
print(test,id(test))
#使用pop(index)根据索引移除元素,然后删除
print(test.pop(1))              #先将索引为1的元素取出来,然后将其删除
print(test,id(test))
#列表的反向输出
test.reverse()
print(test,id(test))        #反向输出,内存地址不变

#列表的拷贝
new_test=test.copy()
print(test,id(test))
print(new_test,id(new_test))        #复制之后,元素是相同的,内存地址发生了改变

#列表元素的修改,使用索引来做修改
test[1]='mysql'
print(test,id(test))                #根据索引修改元素的值,但是内存地址不变
# 清除所有元素
test.clear()
print(test,id(test))        #列表中的所有元素都没了,但是内存地址不变

列表的排序

  • 列表对象的sort方法
lst=[4,5,10,3,60,89,40]
print('原列表',lst)

#排序,默认是升序
lst.sort()
print('升序后',lst)

#排序,降序
lst.sort(reverse=True)
print(lst)
lst2=['Banbana','apple','Orange','cat']
print('原列表:',lst2)
#生序排序,先排大写,再排小写
lst2.sort()
print('升序',lst2)

#降序排列
lst2.sort(reverse=True)
print('降序',lst2)

#忽略大小写进行比较
lst2.sort(key=str.lower)
print('忽略大小写',lst2)
  • 内置函数sorted()
lst=[4,56,30,20,10,100,98,28]
print('原列表:',lst)

#使用sorted排序,默认是升序
asc_lst=sorted(lst)
print('原列表:',lst)
print('升序排序',asc_lst)

#降序排序,将reverse改成true
desc_lst=sorted(lst,reverse=True)
print('降序排序:',desc_lst)

lst2=['banana','apple','Cat','Orange']
print('原列表:',lst2)
#忽略大小写排序
new_lst2=sorted(lst2,key=str.lower)
print('原列表:',lst2)
print('忽略大小写排序:',new_lst2)

使用列表生成式来生成列表


import random
lst=[i for i in range(1,11)]
print(lst)

lst=[i*i for i in range(1,11)]
print(lst)

#自动产生一个1-100之间的列表里有10个随机数
lst=[random.randint(1,100) for _ in range(1,11)]
print(lst)

#从列表中选择符合条件的元素去组成新的列表
lst=[i for i in range(10) if i%2==0]
print(lst)

二维列表的创建

lst=[
    ['城市','环比','同比'],
    ['北京',102,103],
    ['上海',104,504],
    ['深圳',100,39]
]
print('二维列表为:',lst)

#for循环遍历二维列表
for row in lst:  #遍历每一行
    for item in row:
        print(item,end='\t')
    print()

#列表生成式,用于生成一个4行5列的二维列表
lst2=[[j for j in range(5)]for i in range(4)]
print(lst2)

元组类型

是python中内置的不可变序列,在python中使用()定义元组,元素与元素之间使用英文的逗号分隔,元组中只有一个元素的时候,逗号也不能省略

元组的创建方式有2种

  • 使用()直接创建元组
#使用小括号创建元组
t=('hello',[10,20,30],'python','world')
print(t)
  • 使用内置函数tuple()创建元组
#使用内置函数 tuple()创建元组
t=tuple('helloworld!')
print(t)
t=tuple([10,20,30,40])
print(t)
print('10在元组中是否存在:',(10 in t))
print('10在元组中不存在:',(10 not in t))
print('最大值:',max(t))
print('最小值:',min(t))
print('t.conut',t.count(10))
print('t.index',t.index(10))

#如果元组中只有1个元素:
t=(10)
print(t,type(t))
#如果元组中只有1个元素,逗号不能删除
y=(10,)
print(y,type(y))

删除元组

del 元组名

#元组的删除
del t
print(t)            #删除以后在输出就会报错了!

元组的访问与遍历

t=('python','hello','world')
#根据索引访问元素
print(t[0])
t2=t[0:3:2]     #元组支持切片操作
print(t2)

#元组的遍历
for item in t:
    print('遍历元组',item)

#for + range()+len()
for i in range(len(t)):
    print('根据索引:',i,t[i])

#使用enumerate()
for index,item in enumerate(t):
    print(index,'---->',item)

for index, item in enumerate(t,start=11):
    print(index, '---->', item)

元组生成式

#元组生成式
t=(i for i in range(1,4))
print(t)
# t=tuple(t)
# print(t)

#遍历
# for item in t:
#     print(item,end=' ')
print(t.__next__())
print(t.__next__())
print(t.__next__())

t=tuple(t)
print(t)

元组和列表的区别

元组: python中的不可变序列,无法实现添加、删除和修改元素等操作、支持切片访问元素、不支持修改操作、访问和处理速度快、可以作为字典的键

列表:可变序列 append()、insert()、remove()、pop()等方法实现添加和删除列表元素
支持切片访问和修改列表中的元素,访问和处理速度慢,不能作为字典的键

字典类型

字典类型是根据一个信息查找另外一个信息的方式构成了“键值对”,它表示索引用的键和对应的值构成的成对关系

字典的创建方式

  • 使用{}直接创建字典

d={key1:value,ke2:value…}

  • 使用内置函数dict()创建字典
    1)通过映射函数创建字典

zip(lst1,lst2

语法结构如下:
dict(key1=value1,ke2=value2…

#(1)创建字典
d={10:'cat',20:'dog',30:'pet',20:'zoo'}
print(d)        #当key相同的时候,value进行了覆盖
#(2) zip函数
lst1=[10,20,30,40]
lst2=['cat','dog','pet','zoo','car']
aaaa=zip(lst1,lst2)
print(aaaa)
# print(list(aaaa))
d=dict(aaaa)
print(d)

#(3) 使用参数创建字典
d=dict(cat=10,dog=20)       #左边的是键(key),右边的是值(value)
print(d)

t=(10,20,30)
print({t:10})       #t时key 10是value,元组是可以作为字典中的key
lst=[10,20,30]
#print({lst:10})     #这里会报错,可变数据类型不能作为键(key)

#字典属于序列
print('max:',max(d))
print('min:',min(d))
print('len:',len(d))

#字典的删除
del  d
print(d)        #这里就会报错提示

注意事项:

字典中的key是无序的

字典的取值

d[key]或者d.get(key)

  • 字典元素的遍历

遍历出key与value的元组
分别遍历出key和value

d={'hello':10,'world':20,'python':30}
#访问字典中的元素
# (1) 使用d[key]
print(d['hello'])
# (2) 使用d.get(key)
print(d.get('hello'))
#二者之间是有区别的,如果key不存在,d[key]会报错,d.get(key)可以指定默认值
# print(d['java'])  会报错,java不存在
print(d.get('java'))        #提示一个none
print(d.get('java','不能存在'))     #不会输出None,而是输出一个不存在

#字典的遍历
for a in d.items():
    print(a)     #key=value组成的一个元素!

#在使用for循环遍历的时候,分别获取key,value
for key,value in d.items():
    print(key,'--->',value)

字典的相关操作方法

d.keys() 获取所有的key数据
d.values() 获取所有的value数据
d.pop(key,default) key存在获取相应的value,同时删除key-value对,否则获取默认值
d.popitem() #随机从字典中取出一个key-value对,结果为元组类型,同时将该key-value从字典中删除
d.clear() 清空字典中所有的key-value对

 #创建字典
d={1001:'李梅',1002:'王华',1003:'张峰'}
print(d)

#向字典中添加元素
d[1004]='张丽'    #直接使用赋值运算向字典中添加元素
print(d)

#获取字典中的所有的key
keys=d.keys()
print(keys)
print(list(keys))
print(tuple(keys))

#获取字典中的所有的value
values=d.values()
print(values)
print(list(values))
print(tuple(values))

#如何将字典中数据转换成key-value的形式,以元组的方式进行展现
lst=list(d.items())
print(lst)

字典的生成式

import random
#字典生成式
d={item:random.randint(1,100)for item in range(4)}
print(d)

#创建两个列表
lst=[1001,1002,1003]
lst2=['成','王','李']
d={key:value for key,value in zip(lst,lst2)}
print(d)

集合类型

python中的集合与数学中的集合的概念是一致的
python中的集合是一个无需不重复的元素序列
集合中只能存储不可变的数据类型
在python中集合使用{}定义 与列表、字典一样,都是pyhton中的可变数据类型

集合的创建与删除方法

  • 使用{}直接创建集合

语法结构:
s={a,b,c,…n}

  • 使用内置函数set()创建集合

语法结构:
s=set(可迭代对象)

  • del直接删除

del 集合名

#{}直接创建集合
from random import randint

s={10,20,30,40}
print(s)
#集合中只能存储不可变数据类型
# s={[10,20],[30,40]}
# print(s)        #不能存放列表,这里直接报错了

#使用set()创建集合
s=set()     #空集合 空集合 的布尔值是False
print(s)

s={}        #创建的是集合还是字典呢?
print(s)
print(s,type(s))        #直接使用{}创创建的字典

s=set('helloworld')     #这样就是集合了
print(s)            #集合是无序的,并且是不重复的

s2=set([10,20,30])
print(s2)

s3=set(range(1,10))
print(s3)

#集合属于序列的一种
print('max',max(s3))
print('min',min(s3))
print('len',len(s3))

print('9在集合中存在嘛?',(9 in s3))
print('9在集合中不存在吗?',(9 not in s3))

#集合的删除操作:
del s3
print(s3)           #报错没有定义

A={10,20,30,40,50}
B={30,50,88,76,20}
#交集操作
print(A&B)
#并集操作
print(A|B)
#差集操作
print(A-B)
#补集操作
print(A^B)

集合的相关操作方法

s.add(x) 如果x不在集合s中,将x添加到集合s中
s.remove(x) 如果x在集合中,将其删除,否则报错
s.clear() 清除集合中的所有的元素

s={10,29,39}
#向集合中添加元素
s.add(100)
print(s)
#删除集合中的元素
s.remove(29)
print(s)
# #清空集合中的元素:
# s.clear()
# print(s)

#集合的遍历操作:
for i in s:
    print(i)

#使用enumerate()函数
for index,i in enumerate(s):
    print(index,'--->',i)

#集合的生成式
s={i for i in range(1,10)}
print(s)

s={i for i in range(1,10) if i%2==1}
print(s)

列表、元组、字典、集合的区别

列表list 可变序列 可重复 有序 []
元组tuple 不可变序列 可重复 有序 ()
字典dict 可变序列 key不可重复 value可重复 无序 {key:value}
集合set 可变序列 不可重复 无序 {}

结构模式匹配(相当于c语言中的switch)

data=eval(input('请输入匹配的数据:'))
match data:
    case {'name':'hjm','age':20}:
        print('字典')
    case [10,20,39]:
        print('列表')
    case (10,20,30):
        print('元组')
    case _:
        print('不成功')

Python中的字符串及正则表达式

字符串的常用操作:

字符串是python中的不可变数据类型

str.lower()str字符串全部转换为小写字母,结果为一个新的字符串
str.upper()str字符串全部转换成大写字母,结果为一个新的字符串
str.split(sep=None)str按照指定的分隔符sep进行分隔,结果为列表类型
str.count(sub) 结果为sub这个字符串在str中出现的次数
str.find(sub)    查询sub这个字符串在str中是否存在,如果不存在结果为-1,如果存在,结果为sub首次出现的索引
str.index(sub) 功能与find()相同,区别主要是查询的子串sub不存在时,程序报错
str.startwith(s)    查询字符串str是否以子串s开头
str.endswith(s)     查询字符串str是否以子串s结尾 
str.replace(old,news)    使用news替换字体字符串s中所有的old字符串,结果是一个新的字符串
str.center(width.fillchar)    字符串str在制定的宽度范围内剧中,可以使用fillchar进行台填充
str.join(iter)iter中的每个元素后面都增加一个新的字符串str
str.strip(chars)      从字符串中去掉左侧和右侧chars中列出的字符串
str.lstrip(chars)     从字符串中去掉左侧chars中列出的字符串
str.rstrip(chars)     从字符串中去掉右侧chars中列出的字符串
  • 示例
 s1='HelloWorld'
s2=s1.lower()
s3=s1.upper()
print(s1,s2,s3,'aa')
email='aa@qq.com'
lst=email.split('@')
print('邮箱名',lst[0],'域名',lst[1])
print('o的次数为:',s1.count('o'))
print('o的索引为:',s1.index('o'))
print('o的首次出现位置为:',s1.find('o'))
print('p的首次出现位置为:',s1.find('p'))        #值为-1,-1为不存在
print('aa.py'.endswith('.py'))
print('aa.py'.startswith('aa'),'aaaaa')
print('aa.txt'.startswith('.py'),'bbbbb') 
print('aa.txt'.endswith('.py'))
s='helloworld'
s1=s.replace('o','a',1)     #将o替换为a  最后一个参数是替换次数,默认是全部替换 
print(s1,'aa')
print(s.center(30,'*'))         #在左右两侧都填充为*
s1='    hello    world    '
print(s1.strip())       #去掉字符串两侧的空格
print(s1.lstrip())      #去掉字符串左侧的空格
print(s1.rstrip())      #去掉字符串右侧的空格
s2='dl-helloworld'
print(s2.strip('ld'))  #去掉指定的ld(dl也会被去除)
print(s2.lstrip('ld'))  #去掉左侧的指定的字符
print(s2.rstrip('ld'))  #去掉右侧的指定的字符

格式化字符串的三种方式:

  • 占位符

%s:字符串格式
%d:十进制整数格式
%f:浮点数格式

  • f-string

python3.6中引入的格式字符串的方式,比{}表明被替换的字符

  • str.format()方法:

模版字符串.format(逗号分隔的参数)

name='马冬梅'
age=18
kg=98.5
#常规用法
print('姓名:%s,年龄:%d,体重:%.0f'%(name,age,kg))
#f-string
print(f'姓名:{name},年龄:{age},体重:{kg}')
#使用字符串format方法
print('姓名:{0},年龄:{1},体重:{2}'.format(name,age,kg))        #0,1,2和name age kg的索引相对应

格式化字符串的详细格式

: 引导符号
填充: 用于填充单个字符
对齐方式: <左对齐 >右对齐 ^居中对齐
宽度: 字符串的输出宽度
, 数字的千分位分隔符
. 精度:浮点数小数部分的精度或者数字串的最大输出长度
类型: 整数类型b\d\o\x\X 浮点数类型:e\E\f%

s='helloworld'
print('{0:*<20}'.format(s))     #字符串的显示宽度为20,左对齐,空白部分使用*填充
print('{0:*>20}'.format(s))     #字符串的显示宽度为20,右对齐,空白部分使用*填充
print('{0:*^20}'.format(s))     #字符串的显示宽度为20,居中对齐,空白部分使用*填充

#居中对齐还有center
print(s.center(20,'*'),'aaa')

#千位分隔符
print("{0:,}".format(987654321))        #每三位一个,
print('{0:.2f}'.format(3.1415926))      #保留两位的浮点数
print('{0:.5}'.format(s))       #规定显示长度为5位,只能显示前5位

#整数类型
a=425
print('二进制:{0:b}\n十进制:{0:d}\n十六进制:{0:x}\n八进制:{0:o}'.format(a))

字符串的编码和解码

字符串编码:

将str类型转换成byte类型,需要使用到字符串的encode()方法

  • 语法格式:

str.encode(encoding=‘utf-8’,errore=/strict/ignore/replace’)

字符串解码:

将byte类型转换成str类型,需要使用到byte类型的decode()方法

  • 语法格式:

byte.decode(encoding=‘utf-8’,errors=‘strict/ignore/replace’)

s='伟大的中国梦'
#编码:
print(s.encode(errors='replace'))       #默认是utf-8
print(s.encode('gbk',errors='replace'))  

数据的验证:

str.isdigit()        #所有字符都是数字(阿拉伯数字)
str.isnumeric()      #所有字符都是数字
str.isalpha()        #所有字符都是字母(包含中文字符)
str.isalnum()        #所有字符都是数字或字母(包含中文字符)
str.islower()        #所有字符都是小写
str.isupper()        #所有字符都是大写
str.istitle()        #所有字符都是首字母大写
str.isspace()        #所有字符都是空白字符(\n、\t等)

示例:

print('123'.isdigit())
print('123'.isnumeric())
print('一二三'.isdigit() )
print('hello你好'.isalpha())
print('hello你好123'.isalpha())
print('hello你好一二三'.isalpha())

数据的处理:

使用str.join()方法进行拼接字符串
直接拼接
使用格式化字符进行拼接

拼接示例

s='hello'
a='world'
print('  '.join([s,a]))
print("  ".join([s,a,'hello','python']))
print('hello',' ','world')
print("%s  %s"%(s,a))
print('{0}  {1}'.format(s,a))

正则表达式

元字符

具有特殊意义的专用字符,例如 ^和$分别表示匹配的开始和结束

.  匹配任意字符(除\n)  
\w  匹配字母、数字、下划线
\W  匹配非字母、数字、下划线
\s  匹配任意空白字符
\S  匹配任意非空白字符
\d  匹配任意十进制数

限定符

用于限定匹配的次数

? 匹配前面的字符0次或者1次  
+ 匹配前面的字符1次或者多次
* 匹配前面的字符0次或者多次
{n}匹配前面的字符n次
{n,}匹配前面的字符最少n次
{n,m}匹配前面的字符最小n次,最多m次

其他字符

区间字符 []    匹配[]中所指定的字符
排除字符 ^     匹配不在[]中指定的字符
选择字符 |     用于匹配|左右的任意字符
转义字符       同python中的转义字符
分组()        改变限定符的作用

re模块

python中的内置模块,用于实现python中的正则表达式操作

re.match(pattern,string,flags=0)    用于从字符串的开始位置进行匹配,如果起始位置匹配成功,结果为Match对象,否则,结果为None
re.search(pattern,string,flags=0)   用于在整个字符串中搜索与第一个匹配的值,如果匹配成功,结果Match对象,否则,结果为None
re.findall(patternstring,flags=0)   用于在整个字符串搜索所有符合正则表达式的值,结果是一个列表类型
re.sub(pattern,repl,string,count,flags=0)    用于实现对字符串中指定子串的替换
re.split(pattern,string,maxsplit,flags=0)    字符串中的spint()方法功能相同,都是分隔字符串

python中的异常处理

  • try…except的语法结构为:
try:
    可能会报出异常的代码
except 异常类型:
    异常处理代码(报错后执行的代码)
  • try…except…except的语法结构为:
try:
    可能会抛出异常的代码
except  异常类型A:
    异常处理代码(报错后执行的代码)
except  异常类型B:
    异常处理代码(报错后执行的代码)

raise

抛出一个异常,从而提醒程序出现了异常情况,程序能够正确的处理这些异常情况

raise关键字的语法结构:
    raise [Exception类型(异常描述信息)]
    
    
try:
    gender=input("请输入您的性别:")
    if gender!='男' and gender !='女':
            raise Exception('性别只能是男或者女')
    else:
        print("您的性别是:",gender)
except Exception as e:
    print(e)

pyhon中的常见的异常类型:

ZeroDivisionError 当除数为0时,引发的异常
IdexError         索引超出范围索引发的异常
KeyError          字典取值时key不存在的异常
NameError         使用一个没有声明的变量时引发的异常
SyntaxError       Python中的语法错误
ValueError        传入的值错误
AttributeError    属性或者方法不存的异常
TypeError         类型不合适引发的异常
IndentationError  不正确的缩进引发的异常

实例:on

try:
    score=eval(input('请输入分数:'))
    if 0<score<=100:
        print("分数为:",score)
    else:
        raise Exception('分数不正确')
except Exception as e:
    print(e)

函数以及内置函数

函数是将一段实现功能的完整代码,使用函数名称进行封装,通过函数名称进行调用,一次编写,多次调用的目的.

  • 内置函数:
print()    输出
input()    输入
list()     列表定义

自定义函数:

def 函数名称(参数列表):
函数体
[return返回值列表]

函数调用:

函数名(参数列表)

def qiuhe(num):     #形式函数
    s=0
    for i in range(1,num+1):
        s=s+i
    print(f'1-{num}之间的累加和为{s}')

#函数的调用:
qiuhe(10)       #10是实际参数
qiuhe(20)       #都是实参
qiuhe(100)
qiuhe(1000)

使用def关键字定义函数,要确定函数的名称,参数的名称、参数的个数,编写函数体(用于实现函数的功能的代码)

函数的调用:

通过函数名称进行函数的调用
对函数的各个参数进行实际的赋值

函数的执行:

使用实际参数与函数功能的实现

函数返回结果:

函数执行结束后,如果使用return返回结果,则结果被返回到函数的调用处

函数的参数传递

  • 位置参数

是指调用时的参数个数和顺序必须与定义的参数个数和顺序相同

def happy_birthy(name,age):#定义两个参数
    print("祝"+name+'生日快乐!')
    print(str(age)+'岁'+'生日快乐!')

happy_birthy('李xxxx',20)            #调用处传递两个参数

#位置参数传递的时候,个数和位置都得相同 
  • 关键字参数

是在函数调研时,使用“形参名称=值”的方法进行传参,传递参数顺序可以与定义时参数的顺序不同

def happy_birthy(name,age):
    print("祝"+name+'生日快乐!')
    print(str(age)+'岁'+'生日快乐!')

happy_birthy(age=20,name='韩子')        #传递参数的时候
  • 默认值参数

是在函数定义时,直接对形势参数进行赋值,在调研时如果该参数不传值,将使用默认值,如果该参数传值,则使用传递的值

  • 可变参数

分为个数可变的位置参数和个数可变的关键字参数,其中个数可变的位置参数是在一个参数前加一颗星(*para),para形式参数的名称,函数调用可接受任意个数的实际参数,并且放到一个元组中.
个数可变的关键字参数是在参数面前加两颗心(**para),在函数调用使用以接受任意多个‘参数=值’形式的参数,并放到一个字典中

#个数可变的位置参数
def fun(*para):
    print(type(para))
    for i in para:
        print(i)

fun(*[10,20,30,40],[10,20,30])

#个数可变的关键字参数
def fun(**kwpara):
    print(type(kwpara))
    for key,value in kwpara.items():
        print(key,'--->',value)

fun(name='韩子',age=18,high=130)    #关键字参数
d={'name':'韩子','age':18,'height':200}
fun(**d)

函数的返回值:

  • 返回值:return

如果函数的运行结果需要在其他函数中使用,那么这函数就应该被定义为带返回值的函数. 函数的运行结果使用return关键字进行返回
return可以出现在函数中任意一个位置,用于结束函数. 返回值可以是一个值,或者多个值,如果返回值是多个,结果是一个元组类型

#函数的返回值的使用
def calc(a,b):
    return a+b

b=calc(10,20)
c=calc(b,1)
print(c) 

变量的作用域

是值变量起作用的范围,根据范围的作用的大小分为局部变量和全局变量

局部变量

在函数定义处的函数和函数内部定义的变量
仅仅在函数内部,函数执行结束,局部变量的生命周期也就结束了

全局变量

在函数定义外的变量或者函数内部使用global关键字修饰的变量
整个程序,程序运行结束,全局变量的生命周期才结束

def calc(a,b):
    s=a+b
    return s
d=calc(10,20)
print(d)        #a,b用做局部变量



a=100            #a作为全局变量
def calc(x,y):
    return a+x+y
print(a)
print(calc(10,20))



a=100            #外部的a是全局变量
def calc(x,y):
    a=10            #这个a是局部变量
    print('a的值为',a)
    return a+x+y
print('a的值为:',a,'aaa')
print(calc(10,20))

匿名函数lambda

是指没有名字的函数,这种函数只能使用一次,一般是在函数的函数体只有一句代码并且只有一个返回值的时候,可以使用匿名函数来简化

语法结构:

result=lamdba 参数列表:表达式

#匿名函数
s=lambda a,b:a+b
print(type(s),s)
print(s(10,20))        使用匿名函数将10+20打印出来

#匿名函数的另外一种使用方法
a=[10,20,30,40,50]
for i in range(len(a)):
    b=lambda x:x[i]  #根据索引取值,b的类型是函数类型(function)
    print(b(a))     #a是实际参数,x是形式参数

#匿名函数的高级用法
student_scores=[
    {'name':'韩子','score':95},
    {'name': '小刘', 'score': 98},
    {'name': '王五', 'score': 96},
    {'name': '李四', 'score': 100}
]
student_scores.sort(key=lambda x: x.get('score'), reverse=True)        #使用lamdba来用x然后取x中的score作为排序对象
print(student_scores)

递归函数:

在一个函数的函数体内调用该函数本身,该函数就是递归函数
一个完整的递归操作由两部分组成,一部分是递归调用,一部分是递归终止条件,一般可以使用if-else结构来判断递归的调用和递归的终止.

常用的内置函数

数据类型转换函数

  • bool(boj) 获取指定对象obj的布尔值
  • str(obj) 将指定对象obj转换成字符串类型
  • int(x) 将x转换成int类型
  • float(x) 将x转换成float类型
  • list(sequence) 将序列转换成列表类型
  • tuple(sequence) 将序列转换成元组类型
  • set(sequence) 将序列转换成集合类型
print('非空字符串的布尔值:',bool('hello'))
print('空字符串的布尔值',bool(''))  #空字符串不是空格字符串
print('空列表的布尔值:',bool([]))
print('空列表的布尔值:',bool(list()))
print('空元组的布尔值:',bool(()))
print('空元组的布尔值:',bool(tuple()))
print("空集合的布尔值:",bool(set()))
print('空字典的布尔值:',bool({}))
print('空字典的布尔值:',bool(dict()))
print('--*'*30)

print("非0数值型的布尔值:",bool(123))
print("整数0的布尔值:",bool(0))
print("浮点数0.0的布尔值:",bool(0.0))

lst=[10,20,30]
print(type(lst),lst)
s=str(lst)
print(type(s),s)

#float类型和str类型转换成int类型:
print(int(98.7)+int('90'))

常用的数学函数

  • abs(x) 获取x的绝对值
  • divmod(x,y) 获取x与y的商和余数
  • max(sequence) 获取sequence的最大值
  • min(sequence) 获取sequence的最小值
  • sum(iter) 对可迭代对象进行求和运算
  • pow(x,y) 获取x的y次幂
  • round(x,d) 对x进行保留d位小数,结果四舍五入
print('绝对值:',abs(100),abs(-1),abs(0))
print('商和余数:',divmod(13,4))
print("最大值:",max('hello'))
print("最大值:",max([10,20,3,4,50]))
print("最大值:",min('hello'))
print("最大值:",min([10,20,3,4,50]))

print('求和:',sum([1,2,3,4,5,6,7,8,9,10]))
print('x的y次幂',pow(2,3))

#四舍五入
print(round(3.1415926))         #3
print(round(3.9415926))         #4
print(round(3.1415926,2))       #保留2位小数
print(round(314.15926,-1))      #向前面保留一位

常用的迭代器操作函数

sorted(iter)          对可迭代对象进行排序
reversed(sequence)    反转序列生成新的迭代器对象
zip(iter1,iter2)      将iter1与iter2 打包成元组并且返回一个可迭代的对象
enumerate(iter)       根据iter对象创建一个enumerate对象
all(iter)             判断可迭代对象iter中所有元素的布尔值是否都为True
any(iter)             判断可迭代对象iter中所有元素的布尔值是否都为False
next(iter)            获取迭代器的下一个元素
filter(function,iter) 通过指定条件过滤序列并且返回一个迭代器对象
map(function,iter)    通过函数function对可迭代对象iter的操作返回一个迭代器对象

示例

lst=[54,56,77,4,567,34]
print(lst)
#排序操作:
lst1=sorted(lst)                #从小到大排序
print(lst1)
lst1=sorted(lst,reverse=True)   #从大到小排序
print(lst1)

lst2=reversed(lst)
print(type(lst2))           #结果需要转换才能看到
print(list(lst2))

#zip
x=['a','b','c','d']
y=[10,20,30,40,50]

a=zip(x,y)
print(type(a),list(a))

#enumerate
enum=enumerate(y,start=11)
print(type(enum),list(enum))

#all
lst2=[10,20,'',30]
print(all(lst2))        #空字符串的布尔值是False,有一个结果是False,结果就是False
print(all(lst))
print(any(lst2))        #有一个True就是True,全为False,结果为False
print(any(lst))

#next
x=['a','b','c','d']
y=[10,20,30,40,50]

a=zip(x,y)
print(next(a))          #a
print(next(a))          #b
print(next(a))          #c
print(next(a))          #d

#filter     用函数作为参数!
def fun(num):
    return num%2==1

obj=filter(fun,range(10))       #将range产生的0-9执行一次fun操作,使用fun作为filter函数的参数
print(list(obj))

#map使用:
def upper(x):
    return x.upper()

new_lst2=['hello','world','python']
c=map(upper,new_lst2)           #用upper作为map函数的参数
print(list(c)) 

常用的其他内置函数:

format(value,format_spec) 将value以format_spec格式进行显示
len(s) 获取s的长度或者s元素的个数
id(obj) 获取对象的内存地址 type(x) 获取x的数据类型
eval(s) 执行s这个字符串所表示的Python代码

#format
print(format(3.14,'20'))        #数值型默认右对齐
print(format('hello','20'))     #字符串默认左对齐
print(format('hello','*<20'))   #<表示左对齐,*表示填充符,20表示显示的宽度
print(format('hello','*>20'))   #>表示左对齐,*表示填充符,20表示显示的宽度
print(format('hello','*^20'))   #^表示居中对齐,*表示填充符,20表示显示的宽度

print(format(3.1415926535,'.2f'))  #3.14
print(format(20,'b'))
print(format(20,'o'))
print(format(20,'x'))
print(format(20,'X'))
print(len('helloworld'))

例子

def get_find(s,lst):
    for item in lst:
        if s==item:
            return True
        else:
            return False
lst=['hello','world','python']
s=input('请输入要判断的字符串:')
a=get_find(s,lst)
print('存在' if a==True  else '不存在')

两大编程思想:

  • 面向对象与面向过程的异同点

面向过程: 事物比较简单,可以用线性思维去解决

面向对象: 事物比较复杂,使用简单的线性思维无法解决

  • 共同点

面向过程和面向对象都是解决实际问题的一种思维方式
二者相辅相成,并不是对立的,解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间的复杂的关系,方便我们分析整个系统,具体到微观操作,仍然使用面向过程的方式来处理.

类和对象

类是怎么来的?

是由n多个对象抽出’像’的属性和行为从而归纳总结出来的一种类别

#自定义数据类型的语法结构为:
class  类名():  #类名的要求是首字母大写
    pass  
    #类相当于图纸,是一个抽象的模版 只有创建对象才能使用
#创建对象的语法格式为:
对象名=类名()

实例:类的创建

class Person():
    pass

class Cat():
    pass

class Dog():
    pass
class Student:
    pass

#创建类 的对象
#对象名=类名()
per=Person()
c=Cat()
d=Dog()
stu=Student()
print(type(per))
print(type(c))
print(type(d))
print(type(stu))

类的组成

类属性—>直接定义在类中,方法外的变量
实例属性—>在__init__方法中,使用self打点的变量
实例方法—>定义在类中的函数,而且自带参数self
静态方法–>使用装饰器@staticmethod修饰的方法
类方法–>使用装饰器@classmethod修饰的方法

class Student():
    #类属性:定义在类中,方法外的变量
    school='北京XX教育'
    # 初始化方法:
    def __init__(self,xm,age):  #xm,age是方法的参数,是局部变量,仅仅限于当前方法中,作用域为整个init方法
        self.name=xm   #=左侧是实例属性,xm是局部变量,这里是一个赋值操作,将局部变量的姓名赋值给实例属性,self.name
        self.age=age    #实例属性的名称和局部变量的名称,可以相同

    #定义在类中的函数称为方法,自带一个参数self
    def show(self):
        print(f'我叫:{self.name},今年:{self.age}岁啦')
    #静态方法:
    @staticmethod
    def sm():
        print('这是一个静态方法,不能调用实例子属性,不能调用实例方法')
    @classmethod
    def cm(cls): #自带一个cls,是class的简写,是类方法
        print("这是一个类方法,不能调用实例属性,也不能调用实例方法")
   

类中对象的创建

 class Student():
    #类属性:定义在类中,方法外的变量
    school='北京XX教育'
    # 初始化方法:
    def __init__(self,xm,age):  #xm,age是方法的参数,是局部变量,仅仅限于当前方法中,作用域为整个init方法
        self.name=xm   #=左侧是实例属性,xm是局部变量,这里是一个赋值操作,将局部变量的姓名赋值给实例属性,self.name
        self.age=age    #实例属性的名称和局部变量的名称,可以相同

    #定义在类中的函数称为方法,自带一个参数self
    def show(self):
        print(f'我叫:{self.name},今年:{self.age}岁啦')
    #静态方法:
    @staticmethod
    def sm():
        print('这是一个静态方法,不能调用实例子属性,不能调用实例方法')
    @classmethod
    def cm(cls): #自带一个cls,是class的简写,是类方法
        print("这是一个类方法,不能调用实例属性,也不能调用实例方法")

stu=Student('hjm',18)   #因为__init__方法中有2个形参所以传入2个变量,self是自带的参数,无需手动传入
#实例属性是使用对象名称进行打点调用的
print(stu.name,stu.age)
#类属性直接使用类名打点调用
print(stu.school)
#实例方法:使用对象名进行打点调用
stu.show()
#类方法:使用@classmethod进行修饰的方法,直接使用类名打点调用
Student.cm()
#静态方法:使用@staticmethod进行修饰的方法,直接使用类名打点调用
Student.sm()

面向对象的三大特征

封装:隐藏内部细节,对外提供操作方式
继承:是在函数调用时候,使用'形参名称=值'的方法进行传参,传递参数顺序可以与定义时候函数的顺序不同
多态:是在函数定义的时候,直接对形式参数进行赋值,在调用时如果该参数不传值,将使用默认值,如果该参数传值,则使用传递的值

权限控制:

是通过对属性或方法添加单下划线、双下划线以及首尾下划线来实现

单下划线开头:以单下划线开头的属性或方法表示protected受保护的成员,这类成员被视为仅供内部使用,允许类本身和子类进行访问,但实际上它可以被外部代码访问
双下划线开头:表示private私有的成员,这类成员只允许定义该属性或者方法的类本身进行访问
首尾下划线:一般表示特殊的方法

实例:

class Student():
    def __init__(self,name,age,gender):
        self._name=name     #self.name是受保护的,只能本类和子类访问
        self.__age=age      #self.__age表示私有 的,只能类本身去访问
        self.gender=gender  #普通的实例属性,类的内部、外部以及类都可以访问
    def _fun1(self): #受保护的
        print('子类以及本身都可访问')
    def __fun2(self): #私有的
        print('只有定义的类可以访问')
    def show(self):#普通的实例方法:
        self._fun1() #类本身去访问受保护的方法
        self.__fun2() #类本身访问私有方法
        print(self._name)
        print(self.__age)

stu=Student('韩子',20,'男') 
print(stu._name)

继承

在python中一个子类可以继承N多个父类
一个父类也可以拥有N多个子类
如果一个类没有继承任何类,那么这个类默认继承的是object类

语法结构:

class 类名(父类1,父类2....,父类N):
     pass    

实例:

class Person: #默认继承了object
    def __init__(self,name,age):    #实例属性
        self.name = name
        self.age = age
    def show(self):     #实例方法
        print(f"大家好,我叫:{self.name},我今年:{self.age}岁")

#student继承Persion类:
class Student(Person):  #小括号中写父类
    #初始化的方法:
    def __init__(self,name,age,stuno):
        super().__init__(name,age)  #调用父类的初始化方法,为name和age赋值
        self.stuno = stuno

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


stu=Student('韩子',20,'1001')
doctor=Doctor('张x',32,'外科')

stu.show()
doctor.show()


#多继承:
    
class FatherA:
    def __init__(self,name):           #初始化方法
        self.name=name                 #实例属性
    def showA(self):                   #实例方法
        print("这是父类A中的方法")

class FatherB:
    def __init__(self,age):         #初始化方法
        self.name=age               #实例属性
    def showB(self):                #实例方法
        print('这是父类b的方法')

class Son(FatherA,FatherB):                 #多继承,继承了多个父类
    def __init__(self,name,age,gender):     #这里需要调用两个父类的初始化方法
    FatherA.__init__(self,name)             #使用父类的名称来区别
    FatherB.__init__(self,age)
    self.gender=gender

son=Son('韩子',20,'男')
son.showA()
son.showB()

方法重写

子类继承了父类就拥有了父类中共有成员和受保护的成员 父类的方法并不能完全适合子类的需要求这个时候子类就可以重写父类的方法
子类在重写父类方法时,要求方法的名称必须与父类方法的名称相同,在子类重写后的方法中,可以通过super().xxx()调用父类中的方法

多态

多态是多种形态,即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用对象的方法
在程序运行过程中根据变量所引用的对象的数据类型,动态决定调用哪个对象中的方法
python语言中的多态,根本不关心对象的数据类型,也不关心类之间是否存在继承关系,只关心对象的行为(方法).只要不同的类中有同名的方法,即可实现多态

实例:

class Person:
    def eat(self):
        print('人吃五谷杂粮')

class Cat:
    def eat(self):
        print('猫喜欢吃鱼')

class Dog:
    def eat(self):
        print('狗喜欢吃骨头')
#三个类中都有一个同名的方法,eat
#编写函数:
def fun(obj):  #obj是函数的形参
    obj.eat()  #通过变量obj调用eat方法

#创建3个类的对象
per=Person()
cat=Cat()
dog=Dog()

fun(per)        #python中的多态,不关心对象的数据类型,只关心对象是否具有同名方法
fun(cat)
fun(dog)

object类

所有类直接或者间接的父类
所有类都拥有object类的属性和方法

object类中特殊的方法
__new__()   由系统调用,用于创建对象
__init__()  创建对象时手动调用,用于初始化对象属性值
__str__()   对象的描述,返回值是str类型,默认输出对象的内存地址
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def show(self):
        print(f'大家好,我叫:{self.name},我今年:{self.age}岁')


per=Person('hjm',20)  #创建对象的时候会自动调用__init__方法
print(dir(per))
print(per,'aasfasf')
per.show()
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    #方法重写
    def __str__(self):
        return '这是一个人类,具有name和age两个实例属性'
        
per=Person('hjm',20)

print(per,'aasfasf')  #这里就不是内存地址,而是__str__方法中的内容,直接输出对象名,实际上是调用了__str__方法
print(per.__str__())  #两个办法都可以

特殊属性

obj.__dict__              对象的属性字典
obj.__class__             对象所属的类
class.__bases__           类的父类元组
class.__base__            类的父类
class.__mro__             类的层次结构
class._subclasses__()     类的子类列表
class A:
    pass
class B:
    pass
class C(A,B):
    def __init__(self,name,age):
        self.name = name
        self.age = age

a=A()
b=B()
c=C('韩子',12)

print("对象a的属性字典:",a.__dict__)
print("对象b的属性字典:",b.__dict__)
print("对象c的属性字典:",c.__dict__)

print("对象A所属的类:",a.__class__)
print("对象B所属的类:",b.__class__)
print("对象C所属的类:",c.__class__)

print("*"*50,end='\n')
print("\n")

print('A类的父类元组:',A.__bases__)
print('B类的父类元组:',B.__bases__)
print('C类的父类元组:',C.__bases__)

print("\n")

print('A类的父类元:',A.__base__)
print('B类的父类元:',B.__base__)
print('C类的父类元:',C.__base__)  #如果继承了N多个父类,结果只能显示第一个父类

print('A类的层次结构:',A.__mro__)
print('B类的层次结构:',B.__mro__)
print('C类的层次结构:',C.__mro__)     #C类首先继承了A,B类,间接继承了Object类

#子类列表:
print("A类的子类列表:",A.__subclasses__())        #A的子类是C类
print("B类的子类列表:",B.__subclasses__())
print("C类的子类列表:",C.__subclasses__())        #无子类,空列表 

类的深拷贝和浅拷贝

变量的赋值

只是形成两个变量,实际上还是指向同一个对象

浅拷贝

拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象

深拷贝

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

类实例:

#使用类来求圆的面积以及周长
class Circle():
    def __init__(self,r):
        self.r = r

    #计算面积的方法:
    def get_area(self):
     return 3.14*self.r*self.r

    #计算周长的方法:
    def get_zhouhcang(self):
        return 2*3.14*self.r

#创建对象:
b=eval(input("请输入圆的半径:"))
c=Circle(b)
#调用类里面的方法:
mianji=c.get_area()
zhouchang=c.get_zhouhcang()

print(f'圆的面积为:{mianji}')
print(f'圆的周长为:{zhouchang}')
#定义学生类录入5个学生信息存储到列表中
class Stuendet():
        #初始化的方法(self.是实例属性)
    def __init__(self,name,age,gender,score):
        self.name=name
        self.age=age
        self.gender=gender
        self.score=score        #给实例属性赋值

    #实例方法:  用于输出信息
    def info(self):
        print(self.name, self.age, self.gender, self.score)

#开始创建对象:
print("请输入5位学生信息:(姓名#年龄#性别#成绩#:")
lst=[]
for i in range (1,6):
    s=input(f'请输入第{i}位学生信息以及成绩:')
    s_lst=s.split('#')  #索引为0的是姓名,索引为1的是年龄,索引为2的是性别,索引为3的是成绩
    #创建学生对象
    stu=Stuendet(s_lst[0],s_lst[1],s_lst[2],s_lst[3])
    #将学生对象添加到列表中
    lst.append(stu)
#遍历列表,调用学生对象的info方法:
for i in lst:  #i的数据类型是student类型
    i.info()

#使用面向对象的思想实现乐器的弹奏:
class Instrument:
 def make_sound(self):
     pass
     
class Erhu(Instrument):
 def make_sound(self):
     print("二胡在弹奏")            #对象的重写
     
class Piano(Instrument):
 def make_sound(self):
     print("钢琴在弹奏")
     
class Violin(Instrument):
 def make_sound(self):
     print("小提琴在弹奏")

#编写一个函数:
def play(a):
 a.make_sound()

#创建对象
erhu=Erhu()
paino=Piano()
Violin=Violin()

#调用方法:
play(erhu)
play(paino)
play(Violin)

子类父类,重写:

#使用面向对象的思想,设计自定义类:描述出租车和家用车的信息:
#父类:
class fulei():
    def __init__(self,chexing,chepai):
        self.chexing = chexing
        self.chepai = chepai
    def kaishi(self):
        print("我能启动")
    def tingzhi(self):
        print("我能停止")
#子类:
class Chuzhuce(fulei):
    def __init__(self,chexing,chepai,gongsi,):
        super().__init__(chexing,chepai)        #调用父类的初始化方法,给他们赋值
        self.gongsi = gongsi                    #给自己的独有属性赋值
    #重写父类的启动停止方法:
    def kaishi(self):
        print("乘客您好!!")
        print(f'我是{self.gongsi}出租车公司,我的车牌是:{self.chepai},您要去哪里?')
    def tingzhi(self):
        print("目的地到了,请您扫码付款,欢迎下次乘坐!")


class Jiayongche(fulei):
    def __init__(self,chexing,chepai,xingming,):
        super().__init__(chexing,chepai)
        self.xingming = xingming

    def kaishi(self):
        print("乘客您好!!")
        print(f'我是{self.xingming},我的车牌是:{self.chepai},我的轿车我做主?')

    def tingzhi(self):
        print("到达目的地了,快去玩儿吧!!")

#对象创建:
chuzuche=Chuzhuce('上海大众迈腾','京A666666','字节跳动')
chuzuche.kaishi()
chuzuche.tingzhi()


sijiazhe=Jiayongche('红旗','家AAAAAAA','韩子')
sijiazhe.kaishi()
sijiazhe.tingzhi()

模块

简介

在python中的一个后缀名为.py的python文件就是一个模块
模块中可以定义函数,类等
模块也可以避免函数、类、变量等名称相互冲突的问题
模块不仅提高了代码的可维护性,同时还提高了代码的可重用性
在给模块命名的时候要求全部使用小写字母,多个单词之间使用下划线进行分隔
如果自定义模块名称与系统内置模块名称相同,那么在导入的时候会优先的导入自定义的模块

分类:

系统内置模块:

有开发人员编写好的模块,在安装python解释器时一同安装成计算机

自定义模块:

一个以.py结尾的文件就是一个模块,新建python问津,实际上就是新建模块

自定义模块的作用:

一是规范代码,将功能相同的函数,类等封装到一个模块中,让代码更易读,另外一个目的与系统内置模块相同,即可以背起她模块调用,提高开发效率.

模块的导入:

模块编写完成就可以被其他模块进行调用,并且使用被调用模块中的功能

import导入方式的语法结构:
    import模块名称 [as 别名]
from ... import导入方式的语法结构:
    from 模块名称 import 变量/函数//*
    
后导入的模块会将之前导入的模块进行一个覆盖
from my_name import info
info()

import my_name as a 


print(a.name)
a.info()

含有__init__.py的文件或者文件夹
可以避免模块名称相冲突的问题

使用import 包名.模块名   导入
包被导入的时候__init__.py中的文件的代码会自动的导入执行

主程序运行:

if__name__== ' __main__' :
    pass

常用的内置模块

在安装python解释器与解释器一起安装进来的模块被称为系统内置模块,也称为标准模块或者标准库

os模块:与操作系统和文件相关操作有关的模块
re模块:用于在Python的字符串中执行正则表达式的模块
random模块:用于产生随机数的模块
json模块:用于对高维数据进行编码和解码的模块
time模块:与时间相关的模块
datetime模块:与日期相关的模块,可以方便的显示日期并且对日期进行运算

random模块:

用于产生随机数的标准库

seed(x)    初始化给定的随机数种子,默认为当前系统时间
random()    产生一个[0.0,1.0]之间的随机小数
randint(a,b) 生成一个[a,b]之间的整数
randrange(m,n,k) 生成一个[m,n]之步长为k的随机整数
uniform(a,b) 生成一个[a,b]之间的随机小数
choice(seq)    从序列中随机选择一个元素
shuffle(seq)    将序列seq中元素随机排列,返回打乱后的序列

实例:

import random
#设置随机数种子
random.seed(10)
print(random.random())
print(random.randint(1,100))
for  i in range(10):
    print(random.randrange(1,100,3))
print()

time模块:

time模块是python中提供的用于处理时间的标准库,可以用来进行时间处理,时间格式化和计时等

time()                获取当前时间戳
localtime(sec)        获取指定时间戳对应的本地时间的struct_time对象
ctime()               获取当前时间戳对应的易读字符串
strftime()            格式化时间,结果为字符串
strptime()            提取字符串的时间,结果为struct_time对象
sleep(sec)            休眠sec秒

%Y        年份         0001~9999
%m        月份         01~12
%B        月名         January~December
%d        日期         01~31
%A        星期         Monday~Sunday
%H        小时(24h制)  00~23
%I        小时(12h制)  01~12
%M        分钟         00~59
%s        秒           00~59

实例:

import time
a=time.time()
print(a)

b=time.localtime()
print(b)
c=time.ctime()
print(c)

d=time.localtime(60)  #60表示60秒  默认的时间是1970.1.1.8时1分
print(type(d),d)
print('年份:',d.tm_year,'月份:',d.tm_mon,'日期:',d.tm_mday,'时:',d.tm_hour,'分:',d.tm_min,'秒:',d.tm_sec,'星期:',d.tm_wday,'今年的多少天:',d.tm_yday)

print(time.ctime())  #获取当前时间,简单易读的字符串


#日期时间格式化:
print(time.strftime("%Y-%m-%d",time.localtime()))       #转换成年月日的表示方式:2025-01-18
print(time.strftime("%H:%M:%S",time.localtime()))       #转换成时分秒表示方式:17:57:41
print('月份的名称:',time.strftime("%B",time.localtime()))
print('星期的名称:',time.strftime("%A",time.localtime()))


time.sleep(2)       #程序暂停2秒然后打印hello world
print('hello world')

datetime模块

datetime模块可以更方便的显示日期并且对日期进行运算

datetime.datetime        #表示日期时间的类
datetime.timedelta       #表示时间间隔的类
datetime.date            #表示日期的类
datetime.time            #表示时间的类
datetime.tzinfo          #时区相关的类

实例:

from datetime import datetime
dt=datetime.now()      #这个模块是 获取当前的系统时间
print('当前的系统时间为:',dt)

#字符串类型转换成datetime类型:
str_datetime='2028年5月1日20点20分'

dt3=datetime.strptime(str_datetime,'%Y年%m月%d日  %H点%M分')
print(type(dt3),dt3)

timedelta类的使用:

from datetime import datetime
from datetime import timedelta
#创建2个datetime类型的对象:
delta1=datetime(2028,10,1)-datetime(2028,5,1)
print('delta1的数据类型是:',type(delta1),'delta1',delta1)
print("2028年5月1日之后的153天是:",datetime(2028,5,1)+delta1)

#通过传入参数的方式创建一个timedelta对象
dt1=timedelta(10)
print("创建一个10天的timedelta对象",dt1)

dt2=timedelta(10,10)
print("创建一个10天10秒的timedelta对象",dt2)

第三方模块

安装与卸载

第三方模块有全球python爱好者,程序员以及各行各业的专家进行开发并且进行维护

语法:

安装
pip install  模块名称  
卸载
pip uninstall 模块名称
升级pip命令的语句结构:
python -m pip install --upgrade pip  #升级的语法
pip insatll 模块名 -i
http://pypi.douban.com/simple --trusted-host pypi.douban.com

pip install requests
pip uninstall requests

常用的第三方模块

被称之为requests库,用于处理HTTP请求的第三方库,该库在爬虫程序中应用非常广泛.使用requests库中的get()函数可以打开一个网络请求,并且获取一个Response响应对象.响应结果中的字符串数据可以通过响应对象的text属性获取,响应结果中除了有字符串数据也有二进制数据,响应结果中的二进制数据可以通过响应对象的content属性获取

Requests模块的使用:(爬虫)

import  requests
import  re
url='https://www.weather.com.cn/weather1d/101010100.shtml'  #用爬虫打开的浏览器上的网页
response=requests.get(url)  #打开浏览器并且打开网址:
#这里设置一下编码格式:
response.encoding='utf-8'
print(response.text)        #响应对象的text属性,使用对象名.属性名  response.text是属性 这里通过爬虫获得的是html页面

city=re.findall('<span class="name">([\u4e00-\u9fa5]*)</span>',response.text)
weather=re.findall('<span class="weather">([\u4e00-\u9fa5]*)</span>',response.text)
wd=re.findall('<span class="wd">(.*)</span>',response.text)
zs=re.findall('<span class="zs">([\u4e00-\u9fa5]*)</span>',response.text)
#print('城市为:',city)
# print('指数为:',zs)
# print('天气为:',weather)
# print('气温为:',wd)
lst=[]
for a,b,c,d in zip(city,weather,zs,wd):
    lst.append([a,b,c,d])

for item in lst:
    print(item)

'''
<span class="wd">28/15℃</span>
<span class="zs">适宜</span>
'''

使用爬虫爬取百度logo

import requests

url='https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"'
response=requests.get(url)

with open('logo.png', 'wb') as file:
    file.write(response.content)
    ```
## 常用的第三方模块
- poenpyxl

> openpyxl模块是用于处理Microsoft Excel文件的第三方库 
> 可以对Excel文件中的数据进行写入和读取

```python
load_wordbook(filename)        打开已存在的表格,结果为工作簿对象
workbook.sheetnames            工作簿对戏那个的sheetnames属性,用于获取所有工作表的名称,结果为列表类型
sheet.append(lst)              向工作表中添加一行数据,新数据接在工作表
workbook.save(excelname)       保存工作簿
Workbook()                     创建新的工作簿对象

pachong.py

import  requests
import  re

#自定义函数:
def get_html():

    url='https://www.weather.com.cn/weather1d/101010100.shtml'  #用爬虫打开的浏览器上的网页
    response=requests.get(url)  #打开浏览器并且打开网址:
#这里设置一下编码格式:
    response.encoding='utf-8'
# print(response.text)        #响应对象的text属性,使用对象名.属性名  response.text是属性 这里通过爬虫获得的是html页面
    return response.text

def pares_html(html_str):
    city=re.findall('<span class="name">([\u4e00-\u9fa5]*)</span>',html_str)
    weather=re.findall('<span class="weather">([\u4e00-\u9fa5]*)</span>',html_str)
    wd=re.findall('<span class="wd">(.*)</span>',html_str)
    zs=re.findall('<span class="zs">([\u4e00-\u9fa5]*)</span>',html_str)

#print('城市为:',city)
# print('指数为:',zs)
# print('天气为:',weather)
# print('气温为:',wd)
    lst=[]
    for a,b,c,d in zip(city,weather,zs,wd):
        lst.append([a,b,c,d])

    return lst
    ```
    ```python
import pachong
import openpyxl
html=pachong.get_html()
lst=pachong.pares_html(html)

#创建一个新的excel工作簿
workbook = openpyxl.Workbook()  #创建对象
#文件中创建工作表
sheet = workbook.create_sheet('景区天气')
#向工作表中添加数据
for item in lst:
    sheet.append(item)
workbook.save('景区天气.xlsx')

pdfplumber可用于从PDf文件中读取内容
Numpy 是python数据分析方向和其他库的依赖库,用于处理数组、矩阵等数据
Pandas是基于Numpy扩展的一个非常重要的数据分析模块,使用Pandas读取Excel数据更加的方便
Matplotlib是用于数据可视化的模块,使用Matplotlib.pyplot可以非常烦拜年的绘制饼图,柱形图,折线图等

文件及IO操作

文件

存储在计算机的存储设备中的一组数据序列就是文件 不同类型的文件通过后缀名进行区分

文件的基本操作

1.打开文件

变量名=open(filename,mode,encoding)

2.操作文件

变量名.read()
变量名.write(s)

3.关闭文件

变量名.close()

def my_write():
    file=open('a.txt','w',encoding='utf-8')
    file.write('伟大的中国梦!')
    file.close()

def my_read():
    file=open('a.txt','r',encoding='utf-8')
    s=file.read()
    print(type(s),s)
    file.close

if __name__=='__main__':
    my_write()  #调用函数
    my_read()

文件的打开模式:

r   以只读方式打开,文件指针在文件的开头,如果文件不存在,程序抛异常
rb  以只读方式打开二进制文件,如图片文件
w   覆盖写模式,文件不存在创建,,文件存在则内容覆盖
wb  覆盖写模式写入二进制数据,文件不存在则创建,文件存在则覆盖
a   追加写模式,文件不存在创建,文件存在,则在文件最后追加内容
+   与w/r/a等一同使用,在原功能的基础上增加同时读写功能

文件的读写方法:

file.read(size)        从文件中对size个字符或者字节,如果没有给定参数,则读区文件中的全部内容
file.readline(size)    读取文件中的一行数据,如果给定参数,则为读取这一行中的size个字符或者字节
file.readlines()       从文件中读取所有内容,结果为列表类型 
file.write(s)          将字符串s写入文件
file.writelines(lst)   将内容全部为字符串的列表lst写入文件
file.seek(offset)      改变当前文件操作指针的位置,英文占用一个字节,中文gbk编码占用2个字节,ut f-8占用3个字节

实例:

def my_write(s):
    #创建文件(打开)文件
    file=open('a.txt','a',encoding='utf-8')
    #写入内容: 
    file.write(s)
    file.write("\n")
    file.close()

def my_write_list(file,lst):
    f=open(file,'a',encoding='utf-8')
    f.writelines(lst)
    f.close() 


if __name__ =='__main__':
    my_write("伟大的中国梦!!!!!")
    my_write("北京欢迎你!!!!!")
    my_write("牛逼啊!!!!!")
    lst=['姓名\t','年龄\t','成绩\t','张三\t','30\t','98']
    my_write_list('a.txt',lst)

实例:

def my_read(filename):
    file=open(filename,'w+',encoding='utf-8')
    file.write('你好啊!') #写入完成,文件的指针是在最后
    #seek 修改文件指针的位置
    file.seek(0)
    s=file.read()
    print(type(s),s)
    file.close()

if __name__=='__main__':
    my_read('b.txt')

文件的复制:

def copy(src,new_path):
    #边读边写操作:
    #打开源文件:
    file1=open(src,'rb')
    #打开目标文件:
    file2=open(new_path,'wb')
    #开始复制,边读边写
    s=file1.read()  #从源文件中读取所有
    file2.write(s)  #向目标文件中写入所有
    #关闭操作:
    file2.close()
    file1.close()   #先打开的后关,后打开的先关

if __name__=='__main__':
    src='a.txt'
    new_path='d.txt'
    copy(src,new_path)
    print('文件复制完毕')

with语句:

称为上下文管理器,在处理文件的时候,无论是否产生异常,都能保证with语句执行完毕后关闭已经打开的文件,这个过程是自动的,无需手动操作的

  • 语法结构:
with open(...) as file:
    pass

实例:

def write_fun():
    with open('aa.txt','w',encoding='utf-8') as file:
        file.write('2022北京冬奥会,欢迎你!')

def read_fun():
    with open('aa.txt','r',encoding='utf-8') as file2:
        a=file2.read()
        print(a)

def copy(src_file,target_file):
    with open(src_file,'r',encoding='utf-8') as file3:
        with open(target_file,'w',encoding='utf-8') as file4:
            file4.write(file3.read()) #将读取的内容直接写入


if __name__=='__main__':
    write_fun()
    read_fun()
    #文件复制:
    copy('aa.txt','bb.txt')

数据的组织维度及存储

成为数据方式或者存储方式,在python中常用的数据组织方式分为一维数据、二维数据和高维数据.

  • 一纬数据

通常采用线性方式组织数据,一般使用Python中的列表,元组或者集合进行存储数据

  • 二维数据

成为表格数据,由行和列组成,类似于Excel表格,在python中使用二维列表进行存储.

  • 高维数据

使用key-value方式进行组织数据,在pyhton中使用字典进行储存数据,在pyhton中内置json模块专门处理json格式的数据

实例:

#存储和读取一纬数据:
def my_write():
    #一维数据,可以使用列表,元组、集合,不能使用字典
    lst=['张三','李四','王五','陈六','郝七','韩子']
    with open('student.csv','w',) as file:
        file.write(','.join(lst))    #将列表转换成字符串

def my_read():
    with open('student.csv','r') as file:
        s=file.read()
        lst=s.split(',')
        print(lst)


if __name__=='__main__':
    my_write()
    my_read()

json模块的常用函数

json.dumps(obj)        将python数据类型转换成json格式过程,编码过程
json.loads(s)          将json格式字符串转换成python数据类型,解码过程
json.dump(obj,file)    与dumps()功能相同,将转换结果存储到文件file中
json.load(file)        与loads()功能相同,从文件file中读入数据

实例:

import json
lst=[
    {'name':'韩子','age':18,'score':90},
    {'name':'张三','age':21,'score':99},
    {'name':'李四','age':19,'score':89}
]

#
s=json.dumps(lst,ensure_ascii=False,indent=4)   #ensure_ascii 防止乱码(正常显示中文)  indent=是缩进,美观用 JSON格式的字符串更具有可读性
print(type(s),s)        #将lst列表编码成json字符串

#解码:
s1=json.loads(s)
print(type(s1),s1)

#编码到文件中
with open('sutdent.txt','w',encoding='utf-8') as file:
    json.dump(lst,file,ensure_ascii=False,indent=4)

#从文件中解码,解码到程序
with open('student.txt','r') as file1:
    aa=json.load(file1)
    print(type(aa),aa)

目录与文件的相关操作:

pyhton内置的与操作系统文件相关的模块,该模块中的语句的执行结果通常与操作系统有关,即有些函数的运行效果在windows操作系统和macos操作系统中不一样

getcwd()            获取当前的工作路径
listdir(path)       获取path路径下的文件和目录信息,如果没有指定path,则获取当前路径下的文件和目录信息
mkdir(path)         在制定路径下创建目录(文件夹)
makedirs(path)      创建多级目录
rmdir(path)         删除path下的空目录
removedirs(path)    删除多级目录
chdir(path)         把path设置为当前目录
walk(path)          边路目录树,结果为元组,包含所有路径名、所有目录列表和文件列表
remove(path)        删除path指定的文件
rename(old,new)     将old重命名为new
stat(path)          获取path指定的文件信息
starfile(path)      启动path指定的文件

实例:

import os
print('获取当前的工作路径:',os.getcwd())·
lst=os.listdir()
print('当前目录下的所有的目录以及文件:',type(lst),'\n',lst)
print('指定路径下的所有的目录以及文件:',type(lst),'\n',os.listdir('/Users/ming/Documents/语言/C语言/test文件'))

#创建目录:
os.mkdir('haohao')      #如果要创建的文件夹存在,程序报错,报错文件已存在
os.makedirs('./haohao/aa/bb')   #创建多级目录

#删除目录:
os.rmdir('./haohao')
os.removedirs('./haohao/aa/bb') #如果删除的目录不存在,程序会报错!

#改变当前的工作路径:
os.chdir("/User/ming",os.getcwd()) #从这里开始,工作路径发生变化

#遍历目录树,相当于递归操作:
for dirs,dirlst,filelst in os.walk("/Users/ming/Documents/语言"):
    print(dirs,dirlst,filelst)

实例:

import os
#删除文件
os.remove('./student.txt')  #如果要删除的程序不存在,程序报错!
#重命名
os.rename('./student.txt','newstudent.txt') 

#转换时间格式
import time 
def date_format(longtime):
     s=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(longtime))
     return s

#获取文件信息
info=os.stat('./newaa.txt')

print(type(info))
print(info)
print("最近一次访问时间:",date_format(info.st_atime))
print('在windwos操作系统中显示的文件创建时间:',date_format(info.st_ctime))
print('最后一次修改时间:',date_format(info.st_mtime))
print("文件的大小(单位是字节):",info.st_size)


#启动路径下的文件:
os.startfile('终端.app')

os.path模块

是os模块的子模块,也提供了一些目录或者文件的操作函数

abspath(path)         获取目录或文件的绝对路径
exists(path)          判断目录或文件在磁盘上是否存在,结果为bool类型,如果目录或者文件在磁盘上存在,结果为True,否则为False
join(path,name)       将目录与目录名或者文件名进行拼接,相当于字符串中的'+'操作
splitext()            分别获取文件名和后缀名
basename(path)        从path中提取文件名
dirname(path)         从path中提取路径(不包含文件名)
isdir(path)           判断path是否具有有效路径
isfile(path)          判断file是否是有效文件

实例:

import os.path
print('获取目录或者文件的绝对路径:',os.path.abspath('./student.txt'))
print('判断目录或者文件在磁盘上是否存在:',os.path.exists('./student.txt'))
print('拼接路径:',os.path.join('/Users/ming/Documents/语言','ccc.txt'))
print('分割文件名和文件后缀名:',os.path.splitext('b.txt'))  #元组类型,索引为0是文件名称,索引为1是文件后缀名
print('提取文件名:',os.path.basename('/Users/ming/Documents/语言/student.txt'))
print('提取路径:',os.path.dirname('/Users/ming/Documents/语言/student.txt'))
print('判断一个路径是否为有效路径:',os.path.isdir('/Users/ming/Documents/语言/')) #存在就是True,不存在就是False

批量创建文件:

import random
import  os
import  os.path

#函数式编程
def create_filename():
    filename_lst=[]
    lst=['水果','烟酒','粮油','肉蛋','蔬菜']  #物资的类别
    code=['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
    for i in range(1,3001):
        filename=''
        #拼接文件有序号
        if i<10:
            filename=filename+'000'+str(i)
        elif i<100:
            filename+='00'+str(i)
        elif i<1000:
            filename+='0'+str(i)
        else:
            filename+=str(i)
        #拼接类别:
        filename+='_'+random.choice(lst)
        #拼接识别码:
        s=''
        for j in range(9):
            s+=random.choice(code)
        filename+='_'+s
        filename_lst.append(filename)
    return filename_lst

def create_file(filename):
    with open(filename,'w') as file:
        pass

if __name__ == '__main__':
    #在指定的路径下创建文件:
    path='./t'
    if not os.path.exists(path):
        os.mkdir(path)
    lst=create_filename()   #调用获取文件名
    #开始创建文件:
    for item in lst:
        create_file(os.path.join(path,item)+'.txt')

批量创建文件夹

import  os
import os.path
def mkdirs(path,num):
    for i in range(1,num+1):
        os.mkdir(path+'/'+str(i))

if __name__ == '__main__':
    path='./newdir'
    if not  os.path.exists(path):
        os.mkdir(path)

    num=eval(input('请输入要创建的目录个数:'))
    mkdirs(path,num)

进程与线程

程序与进程

程序:英文单词为Program,是指一系列有序指令的集合,使用编程语言所编写,用于实现一定的功能 进程:启动后的程序,系统会为其分配内存空间

创建进程的方式:

  • 第一种创建进程的语法构:

Process(group=None,target,name,args,kwargs)

  • 参数说明:
group:表示分组,实际上不使用,值默认为None即可
target:表示子进程要执行的任务,支持函数名
name:表示子进程的名称
args:表示调用函数的位置参数,以元组的方式进行传递
kwargs:表示调用函数的关键字参数,以字典的形式进行传递
  • 常用的方法和属性
name          当前进程实例别名,默认为Process-N
pid           当前进程对象的PID值
is_alive()    进程是否执行完,没执行完结果为True,否则为False
join(timeout) 等待结束或者等待timeout秒
start()       启动进程
run()         如果没有指定target参数,则启动进程后,会调用父类中的run方法
terminate()   强制终止进程

并发和并行

并发:是指两个或者多个事件同一时间间隔发生,多个任务被交替轮换着执行,比如A事件是吃苹果,在吃苹果的过程中有快递员敲门让你收下快递,收快递就是事件B,那么收完快递继续吃没吃完的苹果,这就是并发

进程之间的通信

进程之间可以通过队列进行通信,队列是一种先进先出的数据结构

  • 创建队列的语法结构:
队列对象=Queue(N) 

常用的方法:

qsize()                获取当前队列包含的消息数量
empty()                判断队列是否为空,为空结果为True,否则为False
full()                 判断队列是否满了,满结果为True,否则为False
get(block=True)        获取队列中的一条信息,然后从队列中移除,block默认值为True
get_nowait()           相当于get(block=False),消息队列为空时,抛出异常
put(item,block=True)   将item消息放入队列,blocak默认为True
put_nowait(item)       相当于put(item,block=False)

实例:

from multiprocessing import Queue
if __name__=='__main__':
    q=Queue(3)
    print('队列是否为空:',q.empty())
    print('队列是否为满:',q.full())

    q.put('hello')
    q.put('world')
    print('队列是否为空:',q.empty())
    print('队列是否为满:',q.full())

    q.put('Python')
    print('队列是否为空:',q.empty())
    print('队列是否为满:',q.full())
    print('队列当中信息的个数:',q.qsize())
    
#出队
    print(q.get())
    print('队列中的信息的个数:',q.qsize())
#入队
q.put_nowait('html')
#q.put_nowait('sql') #queue.Full
#q.put('sql')  不报错,会一直等待,等到队列中有空位置

#遍历:
if not q.empty():
    for i in range(q.qsize()):
        print(q.get_nowait()) #nowait() 不等待
print('队列是否为空:',q.empty())
print('队列是否满',q.full)
print("队列中消息的个数:",q.qsize())

线程

线程是CPU可以调度的最小单位,被包含在进程中,是进程中实际的运作单位,一个进程中可以拥有N多个进程并发执行,而每个进程并发执行不同的任务

创建线程的语法结构:

t=Thread(group,target,name,args,kwargs)
参数说明:
group:创建线程对象的进程组
target:创建的线程对象所要执行的目标函数
name:创建线程对象的名称,默认为Tread-n
args:用元组以位置参数的形式传入target对应函数的参数
kwargs:用字典以关键字的形式传入target对应函数的参数

实例:

import threading,time
from threading import Thread
#编写函数:
def test():
    for i in range(3):
        time.sleep(1)
        print(f"线程:{threading.current_thread().name}正在执行{i}")

if __name__=='__main__':
    start=time.time()
    print("主线程开始执行")
    #线程:
    lst=[Thread(target=test) for i in range(2)]

    for item in lst:#遍历线程对象列表,item时Thread类型的数据类型
        item.start()

    for item in lst:
        item.join() #阻塞主线程
        
    print(f'一共耗时:{time.time()-start}')

网络编程

Socket对象的常用方法

bind((ip,port))     绑定ip地址和端口
listen(N)           开始TCP监听,N表示操作系统挂起的最大连接数,取值范围1-5之间,一般设置为5
accept()            被动接受TCP客户端连接,阻塞式
connect((ip,port))  主动初始化TCP服务器连接
recv(size)          接受TCP数据,返回值为字符串类型,size表示要接受的最大数据量 
send(str)           发送TCP数据,返回值是要发送的字节数量
sendall(str)        完整发送TCP数据,str中的数据发送到连接的套接字,返回之前尝试发送的所有数据,如果成功则为None,失败则抛出异常
recvfrom()          接受UDP数据,返回值为一个元组(data,address),data表示接受的数据,address表示发送数据的套接字地址
sendto(data,(ip,port))  发送UDP数据,返回值是发送的字节数
close()             关闭套接字

TCP编程

  • tcp服务器端编程的流程
    1.使用socket类创建一个套接对象
    2.使用bind((ip,port))方法绑定IP地址和端口号
    3.使用listen()方法开始TCP监听
    4.使用accept()方法等待客户端的连接
    5.使用recv()/send()方法接收/发送数据
    6.使用close()关闭套接字
  • TCP客户端的编程流程
    1.使用socket类创建一个套接字对象
    2.使用connect((hots,port))设置连接的主机IP和主机设置的端口号
    3.使用recv()/send()方法接收/发送数据
    4.使用close()关闭套接字
    TCP编程客户端与服务器端运行有先后,先启动运行服务器端,然后启动运行客户端,连接建立后双方谁先发送数据都可以
服务器端:
from socket import socket,AF_INET,SOCK_STREAM
#AF_INET用于Internet之间的进程通信
#SOCK_STREAM #表示使用TCP协议编程

#创建socket对象:
server_socket=socket(AF_INET,SOCK_STREAM)
#开始绑定ip地址和端口号:
ip='127.0.0.1'
port=8888
server_socket.bind((ip,port))

#开始使用Listen()监听
server_socket.listen(5)
print('服务器已经启动')

#等待客户端的连接:
client_socket,client_addr=server_socket.accept()  #系列解包赋值

#接收来自客户端的数据:
data=client_socket.recv(1024)
print('客户端发送过来的数据为:',data.decode('utf-8'))  #要求客户端发送过来的数据是使用utf-8进行编码的

#关闭socket
server_socket.close()


客户端:
import socket #
#创建socket对象
client_socket=socket.socket()
#ip地址和主机端口:
ip='127.0.0.1'
port=8888
client_socket.connect((ip,port))
print('与服务器的连接建立成功!')

#发送数据:
client_socket.send('Welcome to python world'.encode('utf-8'))
#关闭
client_socket.close()
print('发送完毕!结束')

服务器端客户端多次通信

服务器端:
import socket
socket_obj=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_obj.bind(('127.0.0.1', 8888))
socket_obj.listen(5)
client_socket,client_addr=socket_obj.accept()
#接收数据
info=client_socket.recv(1024).decode('utf-8')
while info!='bye':
    if info!=' ':
        print('接收到的数据是:',info)
    #准备发送的数据:
    data=input('请输入要发送的数据:')

    #服务器端开始回复客户端:
    client_socket.send(data.encode('utf-8'))
    if data=='bye':
        break
    info=client_socket.recv(1024).decode('utf-8')  #改变变量

client_socket.close()
socket_obj.close()

客户端:
import socket
#创建对象
client_socket=socket.socket()
client_socket.connect(('127.0.0.1',8888))
print('连接建立完成!')

#客户端先发送数据:
info=''
while info!='bye':
    #准备发送的数据
    send_data=input('客户端要发送的数据:')
    client_socket.send(send_data.encode('utf-8'))
    if send_data=='bye':
        break 
    
    #接受数据:
    client_socket.recv(1024).decode('utf-8')
    
    print('收到服务器的数据:',info)

client_socket.close()

UDP编程

  • UDP服务器端:
    1.使用socket类创建一个套接字对象
    2.准备发送的数据
    3.定义接受方的IP地址和端口号
    4.使用sendto()方法发送数据
    5.关闭socket对象
  • UDP客户端:
    1.使用socket类创建一个套接字对象
    2.使用bind()方法绑定IP地址和端口号
    3.使用recvfrom()方法接受和发送过来的数据
    4.关闭socket对象
    UDP编程接受方与发送方启动运行无先后,但是先启动的先发送, 否则数据会丢包
服务器端:

from socket import  socket,AF_INET,SOCK_DGRAM
send_socket=socket(AF_INET,SOCK_DGRAM) #SOCK_DGRAM表示是UDP的数据
data=input('请输入要发送的数据:')
#指定接收方的ip地址河端口:
ip_port=('127.0.0.1',8888)
send_socket.sendto(data.encode('utf-8'),ip_port)
#接收来接收方的回复数据
recv_data,addr=send_socket.recvfrom(1024)
print('接收到的数据为:',recv_data.decode('utf-8'))
send_socket.close()

服务端:

from socket import socket,AF_INET,SOCK_DGRAM
recv_socket=socket(AF_INET,SOCK_DGRAM)
recv_socket.bind(('127.0.0.1',8888))

recv_data,addr=recv_socket.recvfrom(1024)
print('接收到的数据为:',recv_data.decode('utf-8'))

data=input('请输入要回复的数据:')

recv_socket.sendto(data.encode('utf-8'),addr)

recv_socket.close()

总结:

和大家交流一些python的知识点,希望对大家有帮助!!


网站公告

今日签到

点亮在社区的每一天
去签到