软件开发,规范你的项目 目录结构,代码规范,遵循PEP8规范等等,让你更加清晰滴,合理滴开发。
软件开发的首要规范就是从设计目录结构开始。
为什么要设计项目目录结构?
- 可读性高: 不熟悉这个项目代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。
- 可维护性高: 定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。
所以,我认为,保持一个层次清晰的目录结构是有必要的。更何况组织一个良好的工程目录,其实是一件很简单的事儿。
较好的目录结构方式(推荐)
具体分析:
#===============>start.py # 开启项目的start文件。 import sys,os BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from core import src if __name__ == '__main__': src.run()
#===============>settings.py # 配置文件,放一些路径或者信息等配置 import os BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DB_PATH=os.path.join(BASE_DIR,'db','db.json') LOG_PATH=os.path.join(BASE_DIR,'log','access.log') LOGIN_TIMEOUT=5 """ logging配置 """ # 定义三种日志输出格式 standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' # log配置字典 LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, }, 'filters': {}, 'handlers': { #打印到终端的日志 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', # 打印到屏幕 'formatter': 'simple' }, #打印到文件的日志,收集info及以上的日志 'default': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'standard', 'filename': LOG_PATH, # 日志文件 'maxBytes': 1024*1024*5, # 日志大小 5M 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { #logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)传递 }, }, }
#===============>src.py # 主要逻辑部分: # 核心逻辑,代码放在这。 from conf import settings from lib import common import time logger=common.get_logger(__name__) current_user={'user':None,'login_time':None,'timeout':int(settings.LOGIN_TIMEOUT)} def auth(func): def wrapper(*args,**kwargs): if current_user['user']: interval=time.time()-current_user['login_time'] if interval < current_user['timeout']: return func(*args,**kwargs) name = input('name>>: ') password = input('password>>: ') db=common.conn_db() if db.get(name): if password == db.get(name).get('password'): logger.info('登录成功') current_user['user']=name current_user['login_time']=time.time() return func(*args,**kwargs) else: logger.error('用户名不存在') return wrapper @auth def buy(): print('buy...') @auth def run(): print(''' 购物 查看余额 转账 ''') while True: choice = input('>>: ').strip() if not choice:continue if choice == '1': buy()
#===============>db.json # 重要数据放在这里 #===============>common.py # 公共组件放在这里:公共功能部分。 from conf import settings import logging import logging.config import json def get_logger(name): logging.config.dictConfig(settings.LOGGING_DIC) # 导入上面定义的logging配置 logger = logging.getLogger(name) # 生成一个log实例 return logger def conn_db(): db_path=settings.DB_PATH dic=json.load(open(db_path,'r',encoding='utf-8')) return dic
#===============>access.log # 日志信息 [2017-10-21 19:08:20,285][MainThread:10900][task_id:core.src][src.py:19][INFO][登录成功] [2017-10-21 19:08:32,206][MainThread:10900][task_id:core.src][src.py:19][INFO][登录成功]
配置文件
文件 + 字典
文件 + 字典
import configparser conf = configparser.ConfigParser() # 创建一个对象 f = open('db.ini','w') conf['DEFAULT'] = { 'session_time_out':60 } conf['186-DB'] = { 'ip':'186.12.33.3', 'port':3306 } conf['192-DB'] = { 'ip':'192.168.16.23', 'port':3306 } conf.write(f) dic = {'1':{'2':'niahoa'} print(conf['186-DB']['ip']) # {'1':{'2':'niahoa'} print(conf.get('186-DB','ip')) conf.read('db.ini') conf['186-DB']['user'] = 'admin' # 内存修改 conf.write(open('db.ini','w')) # 将内存中所有重新写了一份 conf.read('db.ini') del conf['186-DB']['port'] conf.write(open('db.ini','w')) # 将内存中所有重新写了一份 print(conf.sections()) # 章节 for i in conf.sections(): print(i) for k in conf.keys(): print(k) for k in conf.items(): print(k)