今日内容

  • 上节作业
  • 单例模式
class Foo:
    pass
obj1 = Foo()#实例,对象
obj2 = Foo()#实例,对象
  • 日志模块(logging)
  • 程序的目录结构

内容回顾 & 作业

1.字符串格式化

msg = '我是%s,年龄%s'%('alex',19,)
msg = '我是%(name)s,年龄%(age)s'% {'name':'alex','age':'19'}
print(msg)
v1 = '我是{0},年龄{1}'.format('alex',19)
v1 = '我是{0},年龄{1}'.format(*('alex',19,))
v2 = '我是{name},年龄{age}'.format(name='alex',age=19)
v2 = '我是{name},年龄{age}'.format(**{'name':'alex','age':19})
print(v1)
print(v2)

2.有序字典

from collections import OrderedDict

info = OrderedDict()
info['k1'] = 123 #__setitem__
info['k2'] = 456

print(info['k1'])#__getitem__
print(info.keys())
print(info.values())
print(info.items())

3.作业

3.1栈和队列

class Stack(object):
    pass
class Queue(object):
    pass

3.2反射

class Cloud(object):
    def xxx(self):
        pass
    def upload(self):
        pass
    def download(self):
        pass
    def run(self):
        #up|C:/xx/xx.zip
        #down|xxx.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,'post',None) #推荐
print(None)

3.3循环过程中删除元素:pass

1、请使用面向对象实现栈(后进先出)

2、请是用面向对象实现队列(先进先出)

3、如何实现一个可迭代对象?

4、看代码写结果

class Foo(object):

    def __init__(self):
        self.name = '武沛齐'
        self.age = 100
obj = Foo()
setattr(Foo, 'email', 'wupeiqi@xx.com')

v1 = getattr(obj, 'email')
v2 = getattr(Foo, 'email')

print(v1, v2)
5、请补充代码(提:循环的列表过程中如果删除列表元素,会影响后续的循环,推荐:可以尝试从后向前找)

li = ['李杰','女神','金鑫','武沛齐']

name = input('请输入要删除的姓氏:') # 如输入“李”,则删除所有姓李的人。

请补充代码
###
li = ['李杰','女神','金鑫','武沛齐']
li = ['李杰','李女神','金鑫','武沛齐']

# name = input('请输入要删除的姓氏:')
for i in range(len(li)-1,-1,-1):
    if li[i].startswith('李'):
        del li[i]
print(li)


6、有如下字典,请删除指定数据。

class User(object):
    def init(self, name, age):
    self.name = name
    self.age = age

info = [User('武沛齐',19),User('李杰',73),User('景女神',16)]

name = input('请输入要删除的用户姓名:')

请补充代码将指定用户对象再info列表中删除。
7、补充代码实现:校园管理系统。

!/usr/bin/env python
-- coding:utf-8 --
class User(object):
    def __init__(self, name, email, age):
        self.name = name
        self.email = email
        self.age = age

    def __str__(self):
        return self.name
class School(object):
"""学校"""

    def __init__(self):
        # 员工字典,格式为:{"销售部": [用户对象,用户对象,] }
        self.user_dict = {}

    def invite(self, department, user_object):
        """
        招聘,到用户信息之后,将用户按照指定结构添加到 user_dict结构中。
        :param department: 部门名称,字符串类型。
        :param user_object: 用户对象,包含用户信息。
        :return:
        """
        pass

    def dimission(self, username, department=None):
        """
        离职,讲用户在员工字典中移除。
        :param username: 员工姓名
        :param department: 部门名称,如果未指定部门名称,则遍历找到所有员工信息,并将在员工字典中移除。
        :return:
        """
        pass

    def run(self):
        """
        主程序
        :return:
        """
        pass
if name == 'main':
obj = School()
obj.run()

请编写网站实现如下功能。
需求:

实现 MIDDLEWARE_CLASSES 中的所有类,并约束每个类中必须有process方法。

用户访问时,使用importlib和反射 让 MIDDLEWARE_CLASSES 中的每个类对 login、logout、index 方法的返回值进行包装,最终让用户看到包装后的结果。
如:

用户访问 : http://127.0.0.1:8000/login/ ,
页面显示: 【csrf】【auth】【session】 登录 【session】 【auth】 【csrf】

用户访问 : http://127.0.0.1:8000/index/ ,
页面显示: 【csrf】【auth】【session】 首页 【session】 【auth】 【csrf】

即:每个类都是对view中返回返回值的内容进行包装。

MIDDLEWARE_CLASSES = [
'utils.session.SessionMiddleware',
'utils.auth.AuthMiddleware',
'utils.csrf.CrsfMiddleware',
]

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()
    method_name = environ.get('PATH_INFO').strip('/')
    if not hasattr(obj,method_name):
        return ["".encode("utf-8"),]
    response = getattr(obj,method_name)()    
    return [response.encode("utf-8") ]

server = make_server('127.0.0.1', 8000,func)
server.serve_forever()

#####
MIDDLEWARE_CLASSES = [
'utils.session.SessionMiddleware',
'utils.auth.AuthMiddleware',
'utils.csrf.CrsfMiddleware',
]

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()
    method_name = environ.get('PATH_INFO').strip('/')
    print(method_name)
    if not hasattr(obj,method_name):
        return ["".encode("utf-8"),]
    response = getattr(obj,method_name)()
    #对字符串的前后进行包装
    # msg = "【auth】【session】 %s 【session】【auth】"%response
    import importlib
    for path in MIDDLEWARE_CLASSES:
        module_path,cls_name = path.rsplit('.',maxsplit=1) # 'utils.session.SessionMiddleware'
        module = importlib.import_module(module_path)#from utils import session
        cls = getattr(module,cls_name)
        obj = cls()
        response = obj.process(response)
    return [response.encode("utf-8") ]

server = make_server('127.0.0.1', 8000,func)
server.serve_forever()

###
class AuthMiddleware(object):
    def process(self,data):
        msg = '【auth】 %s 【auth】' % data
        return msg
###
class CsrfMiddleware(object):
    def process(self,data):
        msg = '【csrf】 %s 【csrf】' % data
        return msg
###
class SessionMiddleware(object):
    def process(self,data):
        msg = '【session】 %s 【session】'%data
        return msg

python每天创建日志 python程序日志_加载

内容详细

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

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

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

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

obj1 = Foo()
obj2 = Foo()
print(obj1,obj2)

单例模式标准

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')
obj1.file_object.read(1)
obj2.file_object.read(1)

2.模块导入

  • 多次导入重新加载
import jd #第一次加载:会加载一遍jd种所有的内容
import jd #由已经加载过,就不再加载
print(456)
import importlib
import jd
importlib.reload(jd)  
print(456)

通过模块导入的特性也可以实现单例模式:

#jd.py
class Foo(object):
    pass
obj = Foo()
#app.py
import jd   #加载jd.py,加载最后会实例化一个Foo对象并赋值给obj
print(jd.obj)

3.日志(模块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 logging
import time
from logging import handlers

# file_handler = logging.FileHandler(filename='x1.log',mode='a',encoding='utf-8')
file_handler = handlers.TimedRotatingFileHandler(filename='x3', 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('你好')

3.1快速使用

import logging
logging.basicConfig(
    filename='cmdb.log',
    format='%(asctime)s-%(name)s-%(levelname)s-%(module)s:%(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p',
    level=logging.ERROR
)
logging.debug('1')
logging.info('2')
logging.info('3')
logging.warning('4')
logging.error('4')
logging.critical('5')

特殊情况:

import logging
logging.basicConfig(
    filename='cmdb1.log',
    format='%(asctime)s-%(name)s-%(levelname)s-%(module)s:%(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p',
    level=logging.ERROR
)
#无效
logging.basicConfig(
    filename='cmdb2.log',
    format='%(asctime)s-%(name)s-%(levelname)s-%(module)s:%(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p',
    level=logging.ERROR
)

logging.critical('5')

注意事项:

#在应用日志时,如果想要保留异常的堆栈信息
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)

4.项目结构目录

  • 脚本

python每天创建日志 python程序日志_python每天创建日志_02

  • 单可执行文件
  • 多可执行文件