反射和单例

约束

# 约束字类中必须写send方法,如果不写,则调用时候就报抛出 NotImplementedError 
class Interface(object):
    def send(self):
        raise NotImplementedError()
        
class Message(Interface):
    def send(self):
        print('发送短信')z
        
class Email(Interface):
    def send(self):
        print('发送邮件')
      
assert # 断言

根据字符串的形式去某个对象中操作他的成员。

  • getattr(对象,"字符串") 根据字符串的形式去某个对象中获取 对象的成员。

    class Foo(object):
        def __init__(self,name):
            self.name = name
    obj = Foo('alex')
    
    # 获取变量
    v1 = getattr(obj,'name')
    # 获取方法
    method_name = getattr(obj,'login')
    method_name()
    
  • hasattr(对象,'字符串') 根据字符粗的形式去某个对象中判断是否有该成员。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from wsgiref.simple_server import make_server
    
    class View(object):
        def login(self):
            return '登陆'
    
        def logout(self):
            return '等处'
    
        def index(self):
            return '首页'
    
    
    def func(environ,start_response):
        start_response("200 OK", [('Content-Type', 'text/plain; charset=utf-8')])
        #
        obj = View()
        # 获取用户输入的URL
        method_name = environ.get('PATH_INFO').strip('/')
        if not hasattr(obj,method_name):
            return ["sdf".encode("utf-8"),]
        response = getattr(obj,method_name)()
        return [response.encode("utf-8")  ]
    
    # 作用:写一个网站,用户只要来方法,就自动找到第三个参数并执行。
    server = make_server('192.168.12.87', 8000, func)
    server.serve_forever()
    
  • setattr(对象,'变量','值') 根据字符串的形式去某个对象中设置成员。

    class Foo:
        pass
    
    
    obj = Foo()
    obj.k1 = 999
    setattr(obj,'k1',123) # obj.k1 = 123
    
    print(obj.k1)
    
  • delattr(对象,'变量') 根据字符串的形式去某个对象中删除成员。

    class Foo:
        pass
    
    obj = Foo()
    obj.k1 = 999
    delattr(obj,'k1')
    print(obj.k1)
    

python一切皆对象,所以以后想要通过字符串的形式操作其内部成员都可以通过反射的机制实现。

importlib

class Stack(object):
    pass

class Queue(object):
    pass
class Cloud(object):
    def upload(self):
        pass

    def download(self):
        pass

    def run(self):
        # up|C:/xxx/xxx.zip
        # down|xxxx.py
        value = input('请用户输入要干什么?')
        action = value.split('|')[0]
        # 最low的形式
        if action == 'up':
            self.upload()
        elif action == 'down':
            self.download()
        else:
            print('输入错误')

        # 构造字典 (*)
        method_dict = {'up':self.upload, 'down':self.download}
         method = method_dict.get(action)
        method()

        # 反射(*)
         method = getattr(self,action) # upload  # self.upload
        method()
class Foo(object):
    def get(self):
        pass

obj = Foo()
# if hasattr(obj,'post'): 
#     getattr(obj,'post')

v1 = getattr(obj,'get',None) # 推荐
print(v1)

单例模式(23种设计模式)

无论实例化多少次,永远用的都是第一次实例化出的对象。

class Foo:
    pass

# 多例,每实例化一次就创建一个新的对象。
obj1 = Foo() # 实例,对象
obj2 = Foo() # 实例,对象
# 单例,无论实例化多少次,都用第一次创建的那个对象。
obj1 = Foo()
obj2 = Foo()

单例模式标准

class Singleton(object):
    instance = None
    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = object.__new__(cls)
        return cls.instance

obj1 = Singleton()
obj2 = Singleton()

# 不是最终,加锁。

文件的连接池

class FileHelper(object):
    instance = None
    def __init__(self, path):
        self.file_object = open(path,mode='r',encoding='utf-8')

    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = object.__new__(cls)
        return cls.instance

obj1 = FileHelper('x')
obj2 = FileHelper('x')

日志(模块 logging)

  • 基本应用

  • 日志处理本质:Logger/FileHandler/Formatter

  • 推荐处理日志方式

    import logging
    
    file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        handlers=[file_handler,],
        level=logging.ERROR
    )
    
    logging.error('你好')
    
  • 推荐处理日志方式 + 日志分割

    import time
    import logging
    from logging import handlers
    # file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
    file_handler = handlers.TimedRotatingFileHandler(filename='x3.log', when='s', interval=5, encoding='utf-8')
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        handlers=[file_handler,],
        level=logging.ERROR
    )
    
    for i in range(1,100000):
        time.sleep(1)
        logging.error(str(i))
    

    注意事项:

    # 在应用日志时,如果想要保留异常的堆栈信息。
    import logging
    import requests
    
    logging.basicConfig(
        filename='wf.log',
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        level=logging.ERROR
    )
    
    try:
        requests.get('http://www.xxx.com')
    except Exception as e:
        msg = str(e) # 调用e.__str__方法
        logging.error(msg,exc_info=True)
    
    sys.modules  # 存储了当前程序中用到的所有模块,反射本文件中的内容
    raise NotImplementedError   
    # print(random.choice([1,2,3,4,5]))   # 验证码 抽奖
    # print(random.sample([1,2,3,4],3))   # 一个奖项抽取多个人
    
    1.获取文件夹的大小
    # import os
    # def dir_size(path):
    #     ret = os.walk(path)
    #     sum_size = 0
    #     for base_path,dir_lst,file_lst in ret:
    #         for file_name in file_lst:
    #             size = os.path.getsize(os.path.join(base_path,file_name))
    #             sum_size += size
    #     return sum_size
    # ret = dir_size(r'‪D:视频全栈 21期day23')
    # print(ret)
    # os.path.abspath()   # 不可能能帮你确认一个文件的绝对路径
    
    # 2.校验两个大文件的一致性
    # import hashlib
    # path1 = r'D:视频全栈21期day145 python fullstack s21day14 回顾和补充:作业题讲解.mp4'
    # path2 = r'D:视频全栈21期day14ack.mp4'
    # import os
    #
    # 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)
    #             md5.update(content)
    #             size -=1024
    #         else:
    #             content = f.read(size)
    #             md5.update(content)
    #             size = 0
    #     return md5.hexdigest()
    
    # print(file_md5(path1)== file_md5(path2))
    
    # with open(path1,mode='rb') as f:   # 10245
    #     while size > 0:
    #         content = f.read(1024)
    #         md5.update(content)
    #         size -= 1024
    
    # 3.发红包
    # 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,5)
    # for i in ret:
    #     print(i)
    
原文地址:https://www.cnblogs.com/feiguoguobokeyuan/p/13560546.html