day27

一、软件开发的目录规范

1.新建项目文件夹

 

bin    用于存放运行程序

core    用于存放的核心代码

conf    用于存放配置文件——用户可以根据个人喜好定制的文件(相当于写了一堆变量,core代码的运行要从conf中的一些变量值为基础运行)

log    用于记录程序的日志

lib     库目录(程序自定义的一些库) 

db    用于存放数据(可能会有)

redme   介绍软件的使用方法

 

软件的目录的定义清晰即可,并不是一定要用以上的规范

 

举例:

开发一个简单的ATM程序:

1.新建ATM文件夹

2.建立子文件夹,并在不同位置,写入代码

ATM\core\src

 1 from lib.common import logger
 2 
 3 def login():
 4     print("登录功能")
 5     log=logger("用户相关日志")
 6     log.debug("xxx登录")
 7 
 8 def register():
 9     print("注册功能")
10     log=logger("用户相关日志")
11     log.info("xx注册了")
12 
13 def transfer():
14     print("转账")
15     log = logger("交易相关日志")
16     log.warning("xx给yy专了一个亿")
17 
18 
19 def withdraw():
20     print("提现")
21 
22 func_dic = {
23     "1": ["登录", login],
24     "2": ["注册", register],
25     "3": ["转账", transfer],
26     "4": ["提现",withdraw]
27 }
28 
29 
30 def run():
31     while True:
32         print("0 退出")
33         for k in func_dic:
34             print(k, func_dic[k][0])
35 
36         choice = input('请输入您的命令编号>>> ').strip()
37         if choice == "0":
38             break
39 
40         if choice in func_dic:
41             func_dic[choice][1]()
42         else:
43             print("输入的命令编号不存在")

 

 

ATM\bin\start

 1 import sys
 2 import os
 3 
 4 # 方案一:在sys.path环境中直接导入(路径直接锁死)
 5 # sys.path.append(r'D:\py18期\day27\代码\ATM\core')
 6 # sys.path.append(r'D:\py18期\day27\代码\ATM\db')
 7 # sys.path.append(r'D:\py18期\day27\代码\ATM\conf')
 8 # sys.path.append(r'D:\py18期\day27\代码\ATM\lib')
 9 
10 # 方案二:优化,将项目的根目录ATM附加到了sys.path,所有ATM子文件夹中的模块导入都可以用from 子文件夹 import...
11 # sys.path.append(r'D:\py18期\day27\代码\ATM')
12 
13 # 改进  直接获取程序运行的地址将其加到sys.path环境变量中去
14 BASE_DIR = os.path.dirname(os.path.dirname(__file__))
15 sys.path.append(BASE_DIR)
16 
17 
18 from core import src
19 
20 if __name__ == '__main__':
21     src.run()
程序一运行默认的将程序所在的文件夹加到sys.path环境中去了

 

ATM\lib\common

 1 # import time
 2 # from conf import settings
 3 # def logger(msg):
 4 #     with open(r'%s' % settings.LOG_PATH, mode='at', encoding='utf-8') as f:
 5 #         f.write("%s %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), msg))
 6 导入logging模块
 7 import time
 8 from conf import settings
 9 import logging.config
10 
11 logging.config.dictConfig(settings.LOGGING_DIC)
12 
13 def logger(log_name):
14     logger1 = logging.getLogger(log_name)
15     return logger1

ATM\conf\setting

 1 import os
 2 
 3 BASE_DIR = os.path.dirname(os.path.dirname(__file__))
 4 
 5 # LOG_PATH = r'%s\log\access.log' % BASE_DIR
 6 LOG_PATH = os.path.join(BASE_DIR,'log','access.log')
 7 
 8 #导入logging模块
 9 # 1、定义三种日志输出格式,日志中可能用到的格式化串如下
10 # %(name)s Logger的名字
11 # %(levelno)s 数字形式的日志级别
12 # %(levelname)s 文本形式的日志级别
13 # %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
14 # %(filename)s 调用日志输出函数的模块的文件名
15 # %(module)s 调用日志输出函数的模块名
16 # %(funcName)s 调用日志输出函数的函数名
17 # %(lineno)d 调用日志输出函数的语句所在的代码行
18 # %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
19 # %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
20 # %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
21 # %(thread)d 线程ID。可能没有
22 # %(threadName)s 线程名。可能没有
23 # %(process)d 进程ID。可能没有
24 # %(message)s用户输出的消息
25 
26 # 2、强调:其中的%(name)s为getlogger时指定的名字
27 l1_format = "%(asctime)s : %(message)s "
28 l2_format = "%(asctime)s %(name)s %(filename)s:%(lineno)d %(levelname)s: %(message)s "
29 
30 LOGGING_DIC = {
31     'version': 1,
32     'disable_existing_loggers': False,
33     'formatters': {
34         'l1': {
35             'format': l1_format
36         },
37         'l2': {
38             'format': l2_format
39         },
40     },
41     'filters': {},
42     'handlers': {
43         #打印到终端的日志
44         'aaa': {
45             'level': 'DEBUG',
46             'class': 'logging.StreamHandler',  # 打印到屏幕
47             'formatter': 'l1'
48         },
49         #打印到文件的日志,收集info及以上的日志
50         'f1': {
51             'level': 'DEBUG',
52             'class': 'logging.FileHandler',  # 保存到文件
53             'formatter': 'l2',
54             'filename': LOG_PATH,
55             'encoding': 'utf-8',
56         },
57     },
58     'loggers': {
59         #logging.getLogger(__name__)拿到的logger配置
60         '': {
61             'handlers': ['aaa', 'f1'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
62             'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
63             'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
64         },
65 
66     },
67 }

 

 

二、ATM位置的补充

 

当我们在写一个软件时,在pycharm中一般把项目文件打开在顶级

 

三、logging模块

1.日志级别

1 CRITICAL = 50 #FATAL = CRITICAL
2 ERROR = 40
3 WARNING = 30 #WARN = WARNING
4 INFO = 20
5 DEBUG = 10
6 NOTSET = 0 #不设置

logging字典的配置

logger     负责产生日志,并给日志打上标签

handler   接受日志(屏幕——终端,文件,接受日志最起码有两个)

formatter   表示日志的格式

logger====>handler====>formatter

 1 # log配置字典
 2 LOGGING_DIC = {
 3     'version': 1,
 4     'disable_existing_loggers': False,
 5     'formatters': {
 6         'standard': {
 7             'format': standard_format
 8         },
 9         'simple': {
10             'format': simple_format
11         },
12     },
13     'filters': {},
14     'handlers': {
15         #打印到终端的日志
16         'console': {
17             'level': 'DEBUG',
18             'class': 'logging.StreamHandler',  # 打印到屏幕
19             'formatter': 'simple'
20         },
21         #打印到文件的日志,收集info及以上的日志
22         'default': {
23             'level': 'DEBUG',
24             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
25             'formatter': 'standard',
26             'filename': logfile_path,  # 日志文件
27             'maxBytes': 1024*1024*5,  # 日志大小 5M
28             'backupCount': 5,
29             'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
30         },
31     },
32     'loggers': {
33         #logging.getLogger(__name__)拿到的logger配置
34         '': {
35             'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
36             'level': 'DEBUG',
37             'propagate': True,  # 向上(更高level的logger)传递
38         },
39     },
40 }

 







posted @ 2021-07-06 20:44  Gnomeshghy  阅读(62)  评论(0)    收藏  举报