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.项目开发

  1. 模块
  • 什么是模块?
    • py文件:已经写好的对程序员直接提供某方面功能的文件。
    • 导入方式
      • import
      • from xxx import xxx
  • 什么是包?
    • 文件夹:存储了多个py文件的文件夹
    • 注意事项
      • 导入一个包,相当于执行包中__init__文件
      • 如果导入的是一个包,包中其它模块默认是不能用的
  1. 规范

    • 项目总目录
      • 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模块
      • db 数据文件

      • lib 扩展模块

      • log 日志文件

5.栈和队列

  • 栈 Stack
    • 后进先出的队列 lifoqueue(last in first out)
  • 队列 Queue
    • 先进先出的队列 fifoqueue(fifo first in first out)

6.反射

  1. 通过 对象 来获取 实例变量、绑定方法
  2. 通过 类 来获取 类变量、类方法、静态方法
  3. 通过 模块名 来获取 模块中的任意变量(普通变量、函数、类)
  4. 通过 本文件 来获取 本文件中的任意变量
  • 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  # 组合

三大特性

  1. 所有的查找名字(调用方法和属性)都是先找自己的,自己没有找父类。
  2. 如果自己和父类都有,希望自己和父类都调用,则通过 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顺序查找上一个类

猜你喜欢

转载自www.cnblogs.com/elliottwave/p/12536360.html