首页 > 其他分享 >第四周总结复习

第四周总结复习

时间:2022-10-23 20:59:33浏览次数:62  
标签:总结 __ 复习 文件 num 模块 print import 四周

一周总结

异常处理

异常常见类型
AttributeError    # 访问的对象属性不存在
ImportError  # 无法导入模块或者对象,主要是路径有误或名称错误    
SyntaxError   # python语法错误
NameError     # 访问一个未声明的变量
IndexError    # 下标索引超出序列范围
KeyError      # 访问字典里不存在的键
IndentationError  #  代码没有正确对齐,主要是缩进错误
IOError        # 输入/输出异常,主要是无法打开文件
OverflowError    # 数值运算超出最大限制
TabError    # Tab和空格混用
TypeError    # 不同类型数据之间的无效操作(传入对象类型与要求的不符合)
ValueError    # 传入无效的值,即使值的类型是正确的

ZeroDivisionError    # 除法运算中除数0 或者 取模运算中模数为0
异常处理语法结构
1.基本语法结构:
    try:
        待检测的代码(可能会出错的代码)
    except 错误类型:
        针对上述错误类型指定的方案
2.查看错误的信息
	try:
     	待检测的代码(可能会出错的代码)
    except 错误类型 as e:
3.针对不同的错误类型定制不同的解决方案
	try:
        待检测的代码(可能会出错的代码)
    except 错误类型 as e: 
  # e就是系统提示的错误信息
4.万能异常 Exceptionn/BaseException
	try:
        待检测的代码(可能会出错的代码)
     except Exception as e:
        针对各种常见的错误类型全部统一处理
5.结合else使用
	try:
        待检测的代码(可能会出错的代码)
    except Exception as e:
        针对各种常见的错误类型全部统一处理
    else:
        try的子代码正常运行结束没有任何的报错后, 在执行else子代码
6.结合finally使用
try:
    待检测的代码(可能会出错的代码)
except Exception as e:
    针对各种常见的错误类型全部统一处理
else:
    try的子代码正常运行结束没有任何的报错后 再执行else代码
finally:
    无论try的子代码是否报错 最后都要执行finally子代码
   
异常处理补充
1.断言
	def zero(s)
    	a = int(S)
        assert a > 0
        print(a)
        return a
    zero(-5)
    assert a>0 判断为True,所以可以继续执行下面的程序。
  assert a<0 判断为False,所以报错AssertionError,程序中断。

2.主动抛出异常
name = 'jason'
if name = 'jason'
	raise Exception('fuck off')
    # raise Exception 翻译:引发异常
else:
    print('正常运行')
异常处理实战应用
1.异常处理能少用就少用
2.被try检测的代码能尽量少就少
3.当代码中可能会出现一些无法控制的情况报错才应该考虑使用
	手机访问网络软件 断网
    编写网络爬虫程序请求数据 断网
    
练习:
    使用while循环+异常处理+迭代器对象 完成for循环迭代取值的功能
    l1 = [11, 22, 33, 44, 55, 66, 77, 88, 99]
    # 将l1 变成迭代器对象
    list_l1 = l1.__iter__()
    # while循环反复执行迭代对象
    while True:
        try:
            print(list_l1.__next__())
        except StopIteration as e:
            break

生成器对象

1.定义阶段就是一个普通函数
2.当函数体内部有yield有关键字,那么再第一次调用函数的时候,并不会执行函数体代码,而是将函数体改成生成器

3.本质
	还是内置有__iter__和__next__的迭代器对象

4.区别
	迭代器对象是解释器自动提供的
    数据类型\文件对象>>>:迭代器对象
     生成器对象是程序员编写出来的
     代码 关键字>>>:迭代器对象(生成器)

5.创建生成器的基本语法
	函数体代码中填写yield关键字
    def my_iter():
        print('good good')
        yield
 """
 1.函数体代码中如果有yield关键字
 	那么函数名加括号并不会执行函数体代码
 	会生成一个生成器对象(迭代器对象)
 """
res = my_iter()
'''2.使用加括号可之后的结果调用__next__才会执行函数体代码'''
res.__next__()
'''3.每次执行完__next__代码都会停在yield位置 下次基于该位置继续往下找第二个yield'''
def my_iter()
	print('123456789')
       	yield 111, 222, 333
        print('魏某z最帅')
        yield 222,333,444
   	    print('努力')
        yield 222,333,444
        print('冲')
        yield 222, 333, 444
     res = my_iter()
     r1 = res.__next__()
     print(r1)
   	 r2 = res.__next__()
     print(r2)
     r3 = res.__next__()
     print(r3)
     r4 = res.__next__()
     print(r4)
    '''4.yield还有点类似return 可以返回返回值'''
       
        
练习:
   # 1.(两个参数)
def my_range(start_num, end_num):
    while start_num < end_num: # 2.
        yield start_num  # yield 类似 return 返回 start_num 3.
        start_num += 1   # 自增1 直到 start_num = end_num 结束


res = my_range(1, 10).__iter__()   # 迭代器对象
while True:
    try:
        i = res.__next__()  # for i in range(1, 10)
        print(i)
    except StopIteration:
        break

2.(一个参数)
def my_range(start_num, end_num=0):
    if end_num == 0:
        end_num = start_num
        start_num = 0
    while start_num < end_num: # 2.
        yield start_num  # yield 类似 return 返回 start_num 3.
        start_num += 1   # 自增1 直到 start_num = end_num 结束
        
        
for i in my_range(10):
    print(i)

3.(3个参数)
def my_range(start_num, end_num=0,step=1):
    if end_num == 0:
        end_num = start_num
        start_num = 0
    while start_num < end_num: # 2.
        yield start_num  # yield 类似 return 返回 start_num 3.
        start_num += step


for i in my_range(1, 10, 2):
    print(i)
yield冷门用法
def eat(name, food=None):
    print(f'{name}'准备用餐)
    while True:
        food = yield 
        print(f'{name}正在吃{food}')

res = eat('jason')
res.__next__()
# 1.将括号内的数据传给yield前面的变量名
# 2.再自动调用__next__
res.send('包子')
res.send('面条')
    
生成器表达式
# 大白话:生成器的简化写法
l1 = [i ** 2 for i in range(100)]
print(l1)  # 列表生成器

l1 = (i ** 2 for i in range(100)) # 生成器对象
print(l1) # <generator object <genexpr> at 0x00000200BB94BAC0>
for i in l1:
    print(i)
索引取值与迭代器取值的差异
l1 = [11, 22, 33, 44, 55]
1.索引取值
	可以任意位置任意次数取值
    不支持无序类型的数据取值
2.迭代取值
	只能从前往后依次取值无法后退
    支持所有类型的数据取值(无序有序)
 ps:两者的使用需要结合实际应用场景

模块

模块简介
1.模块的本质
	内部具有一定的功能(代码)的py文件
2.python模块的表现模式
	1.py文件(py文件也可以称之为模块文件)
    2.含有多个py文件的文件夹(按照模块功能的不同划分不同的文件夹储存)
    3.已被翻译为共享库或DLL的c或者C++扩展(了解)
    4.使用c编写并链接到python解释器的内置模块(了解)
模块的分类
1.自定义模块
	我们自己写的模块文件.py
2.内置模块
	python解释器提供的模块
3.第三方模块
	别人写的模块文件(python背后的大佬)
导入模块的两种句式
"""
强调:
	1.一定要搞清楚谁是执行文件 谁是被导入文件
	2.以后开发项目的时候py文件的名称一般都是纯英文 甚至不会有中文和空格
	01 作业讲解.py      不会出现
	test.py views.py    出现
	3.导入模块文件不需要填写后缀名

"""

1.import 句式
	以 import a为研究底层原理
   """
   1.先产生执行文件的名称空间
   2.执行被导入文件的代码将产生的名字放入被导入文件的名称空间中
   3.再执行文件中的名称空间产生一个模块的名字
   4.在执行文件中使用的该模块点名的方式使用模块名称空间中所有的名字 .name . 
   """

2. from...import...句式
	以from a import name,func1为列研究底层原理
    """
    1.先产生执行文件的名称空间
    2.执行被导入文件的代码将产生的名字放入被导入文件的名称空间中
    3.在执行文件的名称空间中产生对应的名字绑定模块名称空间中对应的名字
    4.在执行文件中直接使用名字就可以访问名称空间中对应的名字
    """
导入模块补充说明
1.import与from...import...两者优缺点
	import句式
    由于使用模块名称空间中的名字都需要模块点名的方式才可以使用 所以不会轻易的被执行文件中的名字替换掉
    from...import...句式
    指名道姓的导入模块名称空间中需要使用的名字 不需要模块点名 但是容易跟执行文件中名字冲突
    
 2.重复导入模块
	解释器只会导入一次 后续重复的导入语句并不会执行
   
3. 起别名
	import weiyejing as wyj
    from weiyejing import weiyejingzuishuai as niubi
    from a import name as n,func1 as f1
    
4.涉及到多个模块导入
	import a
     import weiyejing
     如果模块功能相似度不高 推荐使用第一种 
相似度高可以使用第二种
	import a, weiyejing
循环导入问题
1.循环导入
	两个文件之间彼此导入并且相互使用各自名称空间中的名字
2.如何解决循环导入问题
	1.确保名字在使用之前就已经准备完毕
    2.我们以后在编写代码的过程中应该尽可能避免出现循环导入
模块的查找顺序
1.内存
	import aaa
    import time
    time.sleep(15)
    print(aaa.name)
    aaa.func1()
    
2.内置
	import time
    print(time)
    print(time.name)
    """
    以后再自定义模块的时候尽量不要与内置模块名冲突
    """
 
3.执行文件所在的sys.path(系统环境环境)
    一定要以执行文件为准!!!
    我们可以将模块所在的路径也添加到执行文件的sys.path中即可
    import sys
    print(sys.path)  # 列表
    
    sys.path.append(r'D:\pythonProject03\day17\mymd')
    import ccc
    print(ccc.name)
绝对导入与相对导入
"""
再次强调:一定要分清楚谁是执行文件!!!
	模块的导入全部以执行文件为准
"""
绝对导入
	from mymd.aaa.bbb.ccc.ddd import name # 可以精确到变量名
     from mymd.aaa.bbb.ccc import ddd # 也可以精确到模块名
     ps: 套路就是按照项目规跟目录一层层往下查找
        
相对导入
	.在路径中表示当前目录
    ..在路径中表示上一层目录
    ..\..在路径中表示上上一层目录
    不在依据执行文件所在的sys.path 而是以模块自身路径为准
    from . import b
    相对导入只能用模块文件中 不能再执行文件中使用
 """
 相对导入使用频率较低 一般用绝对导入即可 结构更加清晰
 """
大白话:多个py文件的集合>>>:文件夹
专业:内部含有__init__.py文件的文件夹(python2必须要求 python3无所谓)
判断文件类型
所有的py文件都可以直接打印__name__对应的值
	当py文件是执行文件的时候__name__对应的值是__main__
    当py文件是被导入文件的时候__name__对应的值是模块名
    
   if __name__ == '__main__':
    print('hahah 我是执行文件 我可以运行这里的子代码')
    
    上述脚本可以用来区分py文件内python代码的执行
    
使用场景
	1.模块开发
    2.项目启动文件
 """
  from a import * *默认是将模块名称空间中所有的名字导入
  __all__ = ['名字1'],['名字2'] 针对*可以限制拿的名字
 """

包的具体使用

虽然python3对包的要求降低了 不需要
__init__.py 也可以识别 但是为了兼容性考虑还是最好加上__init.py

1.如果只想用包中的几个模块 那么还是按照之前的导入方式即可
	from aaa import md1,md2
2.如果直接导入包名
	import aaa
    导入包名其实就是导包下面的__init__.py,该文件内有什么名字 就可以通用包点名什么名字

编程思想的转变

"""
1.面条版阶段
	所有代码全部堆叠再一起
2.函数版阶段
	根据功能的不同封装不同的函数
3.模块版阶段
	根据功能的不同拆分成不同的py文件
"""

"""
第一个阶段可以看成是直接将所有的数据放在C盘
	视频 音频 文本 图片
第二个阶段可以看成是将C盘下的数据分类管理
	视频文件夹 音频文件夹 文本文件夹 图片文件夹
第三个阶段可以看成是将C盘下的数据根据功能的不同划分到更合适的位置
	系统文件夹 C盘	
	视频文件夹 D盘
	图片文件夹 E盘
ps:类似于开公司(小作坊 小公司 上市公司)
	为了资源的高效管理
"""

软件开发目录规范

1.文件及目录的名字可以变换 但是思想似乎不变的分类的管理
2.目录规范主要规定开发程序的过程中 针对不同的文件功能需要做不同的分类

# project 项目文件夹
1.bin文件夹 主要存放项目启动文件
start.by 启动文件可以放在bin目录下 也可以直接在项目根目录

2.conf文件夹 主要存放项目配置文件
settings.py 里面存放项目的默认设置 一般都是大写

3.core文件夹 主要存放项目核心文件
scr.py 里面放项目的而核心功能

4.interface文件夹 主要存放项目接口文件
goods.py 根据具体业务逻辑划分对应的文件
	userpy account.py

5.db文件夹 主要存放项目相关数据
userinfo.txt
db_handler.py 存放数据库操作相关的代码

6.log文件夹 主要存放项目日志文件
	log.log
    
7.lib文件夹 主要存放项目公共功能
common.py

8.readme文件 主要存放项目相关说明

9.requirements.txt文件 主要存放项目所需要模块和版本

常见内置模块之collections模块

colltctions模块简介
1.namedtuple:生成可以使用名字来访问元素内容的tuple
2.deque:双端队列,可以快速的从另一侧追加和推出对象
3.Count: 计数器,主要用于计数
4.OrderedDict: 有序字典
5.defaultdict:带有默认值的字典
nametuple具名元组
1.具名元组 namedtuple
  from collections import namedtuple
"""
python标准库collections中定义了具名元组(namedtuple)工厂函数,它可以构建带字段名的元组。
"""
point = namedtuple('点', ['x', 'y', 'z'])
p1 = point(1,2,3)
print(p1) # 点(x=1, y=2, z=3)


内部元素都是字符串的列表或元组;

例如['商品','单价','数量']或 ('商品','单价','数量')

 以英文逗号','分隔的长字符串。字段名必须符合以下规则:

例如'商品,单价,数量' 

from collections import namedtuple
point = namedtuple('衣服',['单价','数量'])
p1 = point('190','35')
print(p1)  # 衣服(单价='190', 数量='35'

card = namedtuple('扑克牌', ['num', 'color'])
c1 = card('A', '黑桃')
c2 = card('A','红桃')
print(c1, c2)
# 扑克牌(num='A', color='黑桃') 
# 扑克牌(num='A', color='红桃')

2.队列
	队列与堆栈
    	队列:先进先出
        堆栈:先进后出
deque的用法
"""
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
   deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈
   """
from collections import deque

q = deque(['wei','jason','kevin','daniel'])
q.append('彭于晏')  # 默认添加在右边尾部
print(q)
q.appendleft('python3')
print(q) # deque(['python3', 'wei', 'jason', 'kevin', 'daniel', '彭于晏'])

"""
deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
"""
q.pop() # 从尾部删除
q.popleft()  # 从头部删除,不能传值
print(q) # deque(['jason', 'kevin'])
 
OrderdDict用法
'使用dict时,key是无序的。在对dict做迭代时,我们无法确定key的顺序。'
如果需要保持Key的顺序, 就可以用到OrderdDict:
 使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
   如果要保持Key的顺序,可以用OrderedDict:
   
d = dict([('name', 'wei'), ('age', '20'), ('sex', 'male'), ('id', '12345679')])
print(d) # dict的Key是无序的
# {'name': 'wei', 'age': '20', 'sex': 'male', 'id': '12345679'} 
'-------------------------------'
od = OrderedDict([('name', 'wei'), ('age', '20'), ('sex', 'male'), ('id', '12345679')])
print(od) # OrderedDict的Key是有序的
# OrderedDict([('name', 'wei'), ('age', '20'), ('sex', 'male'), ('id', '12345679')])
print(od['name']) # 获取key对应的值内容wei

'OrderdDict的key会按照插入顺序排列,不是key本身排序'
form collections import OrderDict、

od = OrderedDict()
od['name'] = 'wei'
od['age'] = 20
od['work'] = '大明星'
od['id'] = 12345678
print(od.keys())  # 按照插入的key的顺序返回 odict_keys(['name', 'age', 'work', 'id'])
defaultdict的用法
有如下值集合 [16, 26, 46, 36, 66, 56, 76, 86, 96, 6…],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
即: {‘k1’: 大于66 , ‘k2’: 小于66}
# 方法一:原生字典解决方式
l1 = [16, 26, 46, 36, 66, 56, 76, 86, 96, 6…]
d1 = {'k1':[],'k2':[]}
for i in l1:
    if i > 66:
        if i in d1:
            break
        else:
            d1['k1'].append(i)
    if i < 66:
        if i in d1:
            break
        else:
            d1['k2'].append(i)
      
 print(my_dict)

方法二:defaultdict字典解决方法

from collections import defaultdict

l1 = [16, 26, 46, 36, 66, 56, 76, 86, 96, 6…]

d1 = defaultdict(list)
for i in l1:
    if i > 66:
        d1['k1'].append(i)
    else:
        d1['k2'].append(i)
  # defaultdict(<class 'list'>, {'k2': [16, 26, 46, 36, 66, 56, 6], 'k1': [76, 86, 96]})

'使用dict时,如果引用的key不存在,就会抛出KeyError。如果希望key不存在,返回一个默认值,就可以使用defaultdict'

from collections import defaultdict

d = defaultdict(lambda: 'N/A')
d['name'] = 'wei'
d['name']  # name 存在 返回具体值'wei'

print(d['age'])  # age不存在 返回默认值 N/A

Counter的用法
"""
Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)
"""
from collections import Counter
cnt = Counter()
for word in ['red', 'blue', 'red','green','blue','blue']:
    cnt[word] += 1
print cnt
# Counter({'blue': 3, 'red': 2, 'green': 1})
其他内容详细:https://www.cnblogs.com/Eva-J/articles/7291842.html

常见内置模块之时间模块

import time
"""
三种表现形式
	1.时间戳
		秒数
	2.结构化时间
		主要是给计算机看的
	3.格式化时间
		主要是给人看的
"""
print(time.time()) # 记录从1970到现在过来多少时间
print(time.localtime()) # time.struct_time(tm_year=2022, tm_mon=10, tm_mday=19, tm_hour=18, tm_min=57, tm_sec=0, tm_wday=2, tm_yday=292, tm_isdst=0)
print(time.strftime('%Y-%m_%d')) #2022-10_19  格式化时间

time.sleep(10) # 让程序原地阻塞指定秒数

import datetime
print(datetime.datetime.now())
print(datetime.datetime.today())
print(datetime.date.today()) 
'''
datetime 年月日 时分秒
date     年月日
time     时分秒(后续会有此规律)
'''

from datetime import date, datetime
print(date.today())
print(datetime.today())
print(datetime.utcnow()) #世界标准时间utc
import datetime
c = datetime.datetime(2017, 5, 23, 12, 20)
print('指定日期:', c)
# 指定日期: 2017-05-23 12:20:00
d = datetime.strptime('2017/9/30', '%Y/%m/%d')
print(d)
e = datetime.strptime('2017年9月30日星期六', '%Y年%m月%d日星期六')
print(e)
f = datetime.strptime('2017年9月30日星期六8时42分24秒', '%Y年%m月%d日星期六%H时%M分%S秒')
print(f)
# 2017-09-30 00:00:00
# 2017-09-30 00:00:00
# 2017-09-30 08:42:24


import datetime
ctime = datetime.date.today()
print(ctime) # 2022-10-19
time_del = datetime.timedelta(days=3)
print(ctime + time_del) # 2022-10-22
print(time_del)# 3 days, 0:00:00

ctime = datetime.datetime.today()
print(ctime) # 2022-10-19 19:26:16.861151
time_del = datetime.timedelta(minutes=20)
print(ctime + time_del) # 2022-10-19 19:46:16.861151

常见内置模块之随机数模块

import random
print(random.random())  # 随机产生0到1之间的小数
print(random.randint(1, 6))  # 随机产生1到6之间的整数
print(random.randrange(1, 100, 2))  # 随机产生指定的整数

print(random.choice(['一等奖', '二等奖', '三等奖', '谢谢惠顾']))  # 随机抽取一个样本  '二等奖'

print(random.sample(['jason', 'kevin', 'tony', 'oscar', 'jerry', 'tom'], 2))  # 随机抽指定样本数  ['tom', 'jerry']
# l1 = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A']  
random.shuffle(l1)  # 随机打乱数据集
print(l1)


'''
产生图片验证码: 每一位都可以是大写字母 小写字母 数字  4位
'''
def get_code(n):
    code = ''
    for i in range(n):
        # 1.先产生随机的大写字母 小写字母 数字
        random_upper = chr(random.randint(65, 90))
        random_lower = chr(random.randint(97, 122))
        random_int = str(random.randint(0, 9))
        # 2.随机三选一
        temp = random.choice([random_upper, random_lower, random_int])
        code += temp
    return code

res = get_code(10)
print(res)
res = get_code(4)
print(res)

标签:总结,__,复习,文件,num,模块,print,import,四周
From: https://www.cnblogs.com/wei0919/p/16819474.html

相关文章