No.24总结
Posted elliottwave
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了No.24总结相关的知识,希望对你有一定的参考价值。
No.24
内容概要
- 模块梳理
- 面向对象
内容回顾和补充
1.单例模式
- 什么是单例模式?
- 应用场景
__new__
方法:创建实例,并且在__init__
之前工作。- new方法在创建对象空间时,还会在空间内创建一个指针指向对象所属类的地址。
2.logging模块
记录目的
- 给用户看
- 银行流水
- 给程序员看
- 统计(访问量等)
- 故障排除
- 用来记录错误,完成代码优化。debug
- 给用户看
basicconfig
- 优点:使用方便
- 缺点:编码问题,不能同时向文件和屏幕输出等。
- logging.debug / logging.warning
logger对象
- 优点:太多
- 缺点:复杂
- 流程
- 创建一个logger对象
- 创建一个文件操作符
- 创建一个屏幕操作符
- 创建一个格式
- 给logger对象 绑定文件和屏幕操作符
- 给文件和屏幕操作符设定格式
- 最后用logger对象来操作
import logging logger = logging.getLogger() # logger对象 fh = logging.FileHandler('log_paper.log') # 文件操作符 sh = logging.StreamHandler() # 屏幕操作符 formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(module)s: %(message)s') # 格式 fh.setFormatter(formatter) # 把格式绑定到文件操作符对象中 sh.setFormatter(formatter) # 绑定到屏幕操作符对象中 logger.addHandler(fh) # 把文件对象放入logger中 logger.addHandler(sh) logger.warning('message')
3.collections模块
OrderedDict
from collections import OrderedDict dic = dict([('a', 1), ('b', 2), ('c', 3)]) print(dic) odic = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) print(odic) for k in odic: print(k, odic[k])
namedtuple ▲
from collections import namedtuple # 可命名元组 # 创建了一个只含有name price teacher 属性的类 course是类名 Course = namedtuple('Course',['name','price','teacher']) python = Course('Python', 19800,'alex') # 创建了一个对象,封装了三个数据,不可进行更改. # 这三个数据在底层是以元组的形式储存,固然这个对象中的值不能修改. print(python) # Course(name='Python', price=19800, teacher='alex') 元组的形式储存数据 print(python.name) print(python.price) # 创建了一个类,这个类没有方法,所有属性的值都不能修改
defaultdict
deque
4.项目开发
- 模块
- 什么是模块?
- py文件:已经写好的对程序员直接提供某方面功能的文件。
- 导入方式
- import
- from xxx import xxx
- 什么是包?
- 文件夹:存储了多个py文件的文件夹
- 注意事项
- 导入一个包,相当于执行包中
__init__
文件 - 如果导入的是一个包,包中其它模块默认是不能用的
- 导入一个包,相当于执行包中
规范
- 项目总目录
bin 程序入口
模块搜索路径
import os import sys base_path = os.path.dirname(os.path.dirname(__file__)) # __file__永远是当前执行文件的绝对路径 sys.path.append(base_path)
conf 配置
- settings.py
src 业务逻辑
- student.py
- from src import core 导入core模块(注意:只有放执行文件的bin目录和项目总目录被添加进搜索路径)
- core.py
- from conf import settings 导入settings模块
- student.py
db 数据文件
lib 扩展模块
log 日志文件
- 项目总目录
5.栈和队列
- 栈 Stack
- 后进先出的队列 lifoqueue(last in first out)
- 队列 Queue
- 先进先出的队列 fifoqueue(fifo first in first out)
6.反射
- 通过 对象 来获取 实例变量、绑定方法
- 通过 类 来获取 类变量、类方法、静态方法
- 通过 模块名 来获取 模块中的任意变量(普通变量、函数、类)
- 通过 本文件 来获取 本文件中的任意变量
hasattr ▲
getattr ▲
# 反射当前文件中的内容 a = 666 import sys print(getattr(sys.modules['__main__'], 'a')) print(getattr(sys.modules['__name__'], 'a'))
setattr
delattr
7.抽象类/接口类
就是给子类一个规范,让子类必须按照抽象类的规范来实现方法。
# Foo就是一个抽象类 class Foo: def func(self): raise NotImplementedError class Son(Foo): def func(self): pass s = Son() s.fun()
内容详细
模块
os 操作系统
path.isfile() 判断一个目录是不是文件
path.isdir() 判断一个目录是不是文件夹
习题
''' 计算任意一个文件夹的大小(考虑绝对路径) 基础需求:这个文件夹中只有文件 进阶需求:这个文件夹中有多层文件夹嵌套,每一个文件夹中含有文件 ''' import os def dir_size(path): total = 0 File = os.walk(path) for file,son_file,papers in File: for paper in papers: paper_path = os.path.join(file, paper) size = os.path.getsize(paper_path) total += size return total dir_size(path)
sys
- sys.path 模块搜索路径 一个模块能否被导入全看sys.path中有没有这个模块的路径
- sys.argv 获取命令行参数
- sys.modules 存储了当前程序中用到的所有模块
datetime
- now() datetime对象
- utcnow()
- strftime(‘%Y-%m-%d %H:%M:%S‘) 格式化时间 datetime转str
- strptime(‘2020-8-18 10:18:18‘, ‘%Y-%m-%d %H:%M:%S‘) str转datetime
- timedelta(days=180) 时间加减
- timestamp(datetime对象)
- fromtimestamp(时间戳时间)
time
- time() 时间戳时间
- sleep(n) 让程序暂停n秒
hashlib 摘要算发模块
md5
# 数据加密 import hashlib md5 = hashlib.md5('盐'.encode('utf-8')) md5.update('str'.encode('utf-8')) print(md5.hexdigest())
# 效验一致性 import hashlib md5 = hashlib.md5() md5.update('hellow'.encode()) # md5.update('hell'.encode()) 切分了字符串最后结果也一样 # md5.update('ow'.encode()) # 296ab79bb0e6b305a21f964bd2ac8531 print(md5.hexdigest()) # 最终结果一样
补充
# f.read(10) # r 模式:读十个字符 # rb模式:读十个字节 # '中国'里面的'中'是一个字符 # 'alex'里面的'a'是一个字符
习题
# 两个大文件一致性校验 '视频图片文件' import os import hashlib path1 = 'test1' path2 = 'test2' def file_md5(path): size = os.path.getsize(path) # 获取文件总字节数 md5 = hashlib.md5() with open(path, mode='rb') as f: while size > 1024: content = f.read(1024) # 每次读1024个字节, md5.update(content) size -= 1024 else: content = f.read() md5.update(content) size = 0 return md5.hexdigest() print(file_md5(path1) == file_md5(path2))
'文本文档' import hashlib path1 = 'test.txt' path2 = 'tes' def file_md5(path, row): # 路径 每次读多少行 md5 = hashlib.md5() count = 0 with open(path, mode='r', encoding='utf-8') as f: while True: for line in f: md5.update(line.strip().encode('utf-8')) count += 1 if count == row: break content = f.readline() md5.update(content.strip().encode('utf-8')) if not content: break return md5.hexdigest() print(file_md5(path1,5) == file_md5(path2,5))
sha
# 一般用sha1算发 import hashlib sha = hashlib.sha1('盐'.encode('utf-8')) sha.update('str'.encode('utf-8')) print(sha.hexdigest())
json
序列化:把其它数据类型转换成 str / bytes 类型
反序列化:str / bytes 类型转换回原数据类型
- 所有的字符串都是双引号
- 最外层只能是列表或字典
- 只支持 int/float/bool/str/list/dict
- 字典的key只能是str(若key是其它类型在反序列化回来时key会变成str)
- 不能连续load多次(两个列表被分别序列化写入文件后,当读取文件时反序列化就会报错)
- 支持所有语言
pickle
- 几乎所有数据类型都能序列化和反序列化
- 支持连续load多次
- 只支持Python
random
randint
choice(可迭代对象)
- 验证码 / 抽奖
sample([1,2,3,4,5], 3)
随机选三个,一个奖抽取多人。
''' 发红包 每一个人能够抢到的金额的概率都是平均的 200 100 50 解决小数的不准确性 ''' # 方式一 import random def red_pack(money, num): ret = random.sample(range(1, money * 100), num - 1) ret.sort() ret.insert(0, 0) ret.append(money * 100) for i in range(len(ret) - 1): yield ((ret[i + 1] - ret[i]) / 100) ret = red_pack(200, 10) for i in ret: print(i) # 方式二 import random def fun(All_money, num): total_money = All_money * 100 Moy = total_money while num > 1: accuracy = total_money / num # 100 / 9 精准价 11.1111 money = total_money // num # 取整价 11 difference = accuracy - money # 差价 0.1111 while True: result = random.randint(0, money) # 每次抢得红包金额 10 if result != 0: break Moy -= result yield result / 100 total_money = total_money - result + difference # 剩余红包金额 100 - 10 + 0.1111 num = num - 1 # 剩余红包数 9 - 1 yield Moy / 100 for i in fun(200, 10): print(i)
random.uniform(1,5)
- 取1到5之间的随机小数,没有位数限制。
shuffle
- 所有的棋牌类游戏,算发
logging
- basicconfig
- logger对象
collections
- OderedDict
- namedtuple
- deque 双端序列
- defaultDict 默认字典,可以给字典的value设置一个默认值。
shutil
- make_archive() 压缩文件
- unpack_archive() 解压文件
- rmtree() 删除目录
- move() 重命名,移动文件
getpass
- getpass 在命令行密文显示输入的内容
copy
- copy
- deepcopy
importlib
- import_module(‘模块名‘)
- 等效于
__import__
(‘模块名‘)
- 等效于
functools
- reduce(函数,可迭代对象)
面向对象
基础概念
- 什么是类
- 具有相同方法和属性的一类事物
- 什么是对象/实例
- 拥有具体属性和动作的个体
- 实例化
- 从一个类得到一个具体对象的过程
组合
一个类的对象作为另一个类对象的实例变量
class C_learn(object): pass python = C_learn() # python是课程类的对象 class Student(object): pass alex = Student() # alex是学生类的对象 alex.course = python # 组合
三大特性
- 所有的查找名字(调用方法和属性)都是先找自己的,自己没有找父类。
- 如果自己和父类都有,希望自己和父类都调用,则通过 super()/指定类名 两种方式调用。
继承
父类/基类/超类
子类/派生类
单继承
- 子类可以使用父类的方法
多继承
查找顺序
- 深度优先:Py2
- 广度优先:Py3
class A: def func(self): print('a') class B(A): def func(self): print('b') class C(A): def func(self): print('c') class D(B, C): def func(self): print('d') obj = D() obj.func() print(D.mro()) # 查看继承查找顺序 # Py2查找顺序:DBAC # Py3查找顺序: DBCA
- 新式类和经典类
- Py2 继承object类就是新式类,默认是经典类。
- Py3 都是新式类,默认继承object类。
- 新式类
- 继承object
- 新式类支持super
- 对于多继承广度优先(C3算法)
- 有mro方法(查看继承查找顺序)
- 经典类
- 不继承object
- 经典类没有super
- 对于多继承深度优先
- 无mro方法
多态
- 一个类表现出来的多种状态
- 鸭子类型
封装
- 广义:类中的成员
- 狭义:私有成员
- __名字
- 只能在类的内部使用,既不能在类外部调用,也不能在子类中调用。
- 外部强制访问:_类名__名字
类成员
- 类变量
- 绑定方法
- 特殊成员
- 类方法 classmethod
- 静态方法 statcmethod
- 属性 property
- 双下方法/魔术方法/内置方法
__new__
构造方法__init__
初始化方法__call__
源码中很容易写这个用发__str__
__enter__
&__exit__
with上下文管理__getitem__
跟中括号访问有关系__setitem__
__delitem__
__add__
__iter__
__dict__
相关内置函数
- issinstance 对象和类之间的关系
- issubclass 类和类之间的关系
- type 类型 类 = type(对象)
- super 遵循mro顺序查找上一个类
以上是关于No.24总结的主要内容,如果未能解决你的问题,请参考以下文章