一、复习(对之前所讲的7天重点内容总概括):
基础数据类型
int float 加减乘除 乘方取余 小数的保留几位小数 round
可以存放任意的数据类型,增删改查
str list tuple 序列 —— index
字符串 split strip startswith join
dict set 散列
for循环 while循环 条件语句
while循环 你不知道要循环多少次
for循环 你知道要循环多少次
条件判断 一条if语句只有一个分支被执行
文件操作:open/close
打开模式
a w r ——直接对字符串操作
ab wb rb ——直接对字节操作
操作系统的编码和python编码不一致的乱码问题
函数
函数基础 :
定义:关键字、参数:位置参数,*args,默认参数(关键字参数)=默认值,**kwargs、返回值
调用:关键字:函数名(),参数:按照位置传,按照关键字传,接收返回值
函数的命名空间:
在函数的内部可以使用外部的变量:读,写改:声明 global改全局,nonlocal是改局部
在外部不能使用函数内部的变量
闭包 —— 装饰器
是在函数的前后添加功能
生成器函数 —— 迭代器 —— 生成器表达式 —— 列表推导式
yield写代码的时候可以尽量用,很好的节省内存
生成器表达式和列表推导时能够很好的简化代码
迭代器 生成器函数(调用不执行)—— 面试之前看
递归函数
大部分的递归都可以用循环实现
递归相比循环来说 并不能节省内存 还占用更多的空间
算法用到的特别多
模块
内置模块
collections namedtuple 有序字典 /默认字典
os 文件和文件夹的操作/和路径相关的/执行操作系统命令
sys sys.path sys.argv
time 三种时间格式 :字符串(格式化) 元祖(结构化) 浮点(时间戳)
random 随机整数 小数 抽取 打乱顺序
re 正则 : findall search
序列化 pickle json shelve
hashlib 摘要算法的模块 文件的一致性校验 加密认证
logging 加日志的模块
configpaser --
扩展模块
自定义的模块
模块和包
面向对象
基础的定义
类 对象 实例化
class 定义 语法
三大特性 : 继承**** 封装*** 多态*
继承 继承的规则 子类可以使用中的所有非私有的名字,前提是子类没有
多继承的查找顺序问题: 经典类深度优先 新式类 广度优先
super不是单纯的寻找父类,而是遵循mro(广度优先)顺序
封装
私有的属性既不能被继承 也不能从类的外部调用
多态 python自带
组合 一个类的对象作为另外一个类对象的属性
反射 : hasattr getattr 用字符串的形式来获取变量
内置方法 :__new__类的构造方法,在init之前执行
二、异常处理
2.1 逻辑错误(ValueError)
inp = int(input('num : ')) # 逻辑错误 ValueError
2.2 、NameError
name # NameError
直接执行:
2.3、IndexError
l = [] # IndexError
l[2]
2.4、举例1
l=[]
try:
l=[]
num=int(input('num: '))
l[num]
except ValueError:print('请输入一个数字')
except IndexError:print('您要找的项目不存在')
执行结果:
举例2:
l=[]
try:
l=[]
num=int(input('num: '))
l[num]
except Exception as e:print(e) 这个是万能异常,所以始终不会执行下面的这句
except IndexError:print('您要找的所以不存在')
执行结果:
总结格式:
# try
# excpet
# except as 起别名的意思
# 找到一个满足条件的其他分支都不走了
# 预料不到的错误 —— 万能异常(Exception)
# except
# except Exception:
# except Exception as e: ---推荐
# 具体的异常处理+万能异常:
# 能够提前预料到的异常都应该用具体的异常去处理,剩下其他的异常用万能异常控制
# 万能异常应该写在最后
举例3:
try:
f = open('a','w')
l = [1]
num = int(input('num : '))
l[num]
except ValueError:print('请输入一个数字')
except IndexError:print('您要找的项目不存在')
except Exception as e:print(e)
else:print('执行else了') # 如果try语句中的代码都顺利的执行了,没有报错,那么执行else中的代码
finally:
print('执行finally了') # 无论如何都会执行
f.close()
执行结果:
总结:
异常处理的语法结构:
# try:
# pass #可能有问题的代码
# except ValueError: # 能预料到的错误
# pass
# except Exception as e:print(e) # 能处理错有的异常
# else:pass # try中的代码没有错误的时候执行
# finally:pass # 无论如何都会执行的
举例4:
class EvaException(BaseException):
def __init__(self,msg):
self.msg=msg
def __str__(self):
return self.msg
obj = EvaException('类型错误')
print(obj)
执行结果:类型错误
小总结:
# assert 1==2 # if条件判断
# try except else finally
# raise 错误类型
# 自定义异常 自定义一个类继承BaseException
# 断言 assert
三、模块
举例1:
my_moudule.py代码:
print('my moudule')
money = 1000
def func():
print('in func',money)
func()
主运行的代码:
# 模块 py
import sys
sys.path.append(r'D:BaiduNetdiskDownloadday8')
# print(sys.path)
import my_moudule as mm
money = 2000
mm.func()
print(mm.money)
#
def func():
print('my func')
func()
mm.func()
执行结果:
my moudule
in func 1000
in func 1000
1000
my func
in func 1000
# 导入一个模块 就相当于执行了这个文件
# 一个模块如果执行多次import是什么效果?只执行一次
# import 和 from import 的区别
# 模块之间不能发生循环引用。
举例2:
my_moudule.py代码和上面的保持一致
主运行代码:
import sys
from my_moudule import func as f,money as m 支持导入多个并且起别名
from my_moudule import *
func()
print(money)
主代码执行结果:
my moudule
in func 1000
in func 1000
1000
# 模块总结
# 能不能导入模块 : sys.path
# 导入模块的顺序 : 内置 扩展 自定义
# 导入模块 : 相当于执行了这个模块,文件中的名字会被存储在一块独立的内存空间中
# import
# 在全局创建了一个模块名,指向属于这个模块的命名空间
# 空间里存储了所有文件中的名字
# 起别名 import ... as ..
# 不推荐一行导入多个模块
# from import 仍然会执行整个文件,文件中的名字会被存储在一块独立的内存空间中
# import后面的名字会出现在全局 ,相当于对独立命名空间中的一个引用
# from import 也支持 as语句 也支持 导入多个名字
# from import * 相当于导入所有名字,*和被导入模块__all__是互相影响的
四、包
包的概念:
# 一组py文件组成的文件夹,在这个文件夹里有一个__init__.py,包
五、网络编程
举例1:TCP协议
server代码:
import socket
sk=socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind(('127.0.0.1',9003))
sk.listen()
conn,addr=sk.accept()
while True:
msg=input('>>')
conn.send(msg.encode('utf-8'))
if msg=='q':break
ret=conn.recv(1024).decode('utf-8')
if ret=='q':break
print(ret)
conn.close()
sk.close()
client代码:
import socket
sk=socket.socket()
sk.connect(('127.0.0.1',9003))
while True:
ret=sk.recv(1024).decode('utf-8')
print(ret)
if ret=='q':break
msg=input('>>')
sk.send(msg.encode('utf-8'))
if msg=='q':break
sk.close()
执行结果:
先执行server代码,再执行client代码,先从server端开始输入,再从client端输入,任何一方输入q,那么程序都终止。
这种只能是一个server对一个client说话,再打开一个client,即使第一个client窗口被关闭,也不能跟第二个client通话
举例2:在举例1基础上改造:
---------------------------------------------------------------------
老师代码:
server端:
import socket
sk = socket.socket() #拿到一个socket实例化对象
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind(('127.0.0.1',9000)) # 一台电脑 65535 - > 操作系统
sk.listen() # 监听
while True: # 无限的接电话
conn,addr = sk.accept() # 阻塞 三次握手完毕
while True: # 接到电话之后无限聊
msg = input('>>>')
conn.send(msg.encode('utf-8')) # 发送数据
if msg == 'q':break
ret = conn.recv(1024).decode('utf-8')
if ret == 'q':break
print(ret)
conn.close()
sk.close()
老师代码client端:
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9000))
while True:
ret = sk.recv(1024).decode('utf-8') # 接收一个数据
if ret == 'q':break
print(ret)
msg = input('>>>')
sk.send(msg.encode('utf-8'))
if msg == 'q':break
sk.close()
-----------------------------------------------------------------
server端代码(myself):
import socket
sk=socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind(('127.0.0.1',9003))
sk.listen()
while True:
conn, addr = sk.accept()
while True:
msg=input('>>')
conn.send(msg.encode('utf-8'))
if msg=='q':break
ret=conn.recv(1024).decode('utf-8')
if ret=='q':break
print(ret)
conn.close()
sk.close()
client端代码(myself):
import socket
sk=socket.socket()
sk.connect(('127.0.0.1',9003))
while True:
ret=sk.recv(1024).decode('utf-8')
print(ret)
if ret=='q':break
msg=input('>>')
sk.send(msg.encode('utf-8'))
if msg=='q':break
sk.close()
执行结果:先执行server,再执行client,再执行client,当第一个clinet输入q之后,第一个client断了,server不断,那么第二个client立马接进来