在python开发中,我们建议采用如下规范:

soft/
├── bin # 程序执行文件目录
│   ├── __init__.py
│   └── start.py # 程序开始执行脚本文件
├── conf # 配置文件目录
│   ├── config.ini # 配置文件
│   ├── __init__.py
│   ├── my_log_settings.py # 日志文件配置脚本
│   └── settings.py # 配置脚本
├── core # 核心模块
│   ├── core.py # 核心功能脚本
│   └── __init__.py
├── db # 数据文件目录
├── lib # 库文件目录
│   ├── __init__.py
│   └── read_ini.py # 库脚本文件
└── log # 日志目录
└── all2.log # 日志文件

首先在 start.py 中要添加项目的环境变量:

bin/

import sys,os

BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))    # 获取项目的根目录
sys.path.append(BASE_DIR) # 将项目的根目录添加到环境变量中 from core import core
from conf import my_log_settings if __name__ == '__main__':
my_log_settings.load_my_logging_cfg()
core.run()

start.py

conf/

[DEFAULT]
user_timeout = 1000 [hkey]
password = 123
money=10000000000

config.ini

import os
import logging.config # 定义三种日志输出格式 开始 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' # 定义日志输出格式 结束 logfile_dir = r'%s\log' %os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # log文件的目录 logfile_name = 'all2.log' # log文件名 # 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
os.mkdir(logfile_dir) # log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name) # 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': logfile_path, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
},
} def load_my_logging_cfg():
logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
logger = logging.getLogger(__name__) # 生成一个log实例
logger.info('It works!') # 记录该文件的运行状态 if __name__ == '__main__':
load_my_logging_cfg()

my_log_settings.py

settings.py

import os
config_path=r'%s\%s' %(os.path.dirname(os.path.abspath(__file__)),'config.ini')
user_timeout=10
user_db_path=r'%s\%s' %(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),\
'db')

settings.py

core/

import logging
import time
from conf import settings
from lib import read_ini config=read_ini.read(settings.config_path)
logger=logging.getLogger(__name__) current_user={'user':None,'login_time':None,'timeout':int(settings.user_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>>: ')
if config.has_section(name):
if password == config.get(name,'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('''
1. 购物
2. 查看余额
3. 转账
''')
while True:
choice = input('>>: ').strip()
if not choice:continue
if choice == '':
buy() if __name__ == '__main__':
run()

core.py

lib/

import logging
import time
from conf import settings
from lib import read_ini config=read_ini.read(settings.config_path)
logger=logging.getLogger(__name__) current_user={'user':None,'login_time':None,'timeout':int(settings.user_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>>: ')
if config.has_section(name):
if password == config.get(name,'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('''
1. 购物
2. 查看余额
3. 转账
''')
while True:
choice = input('>>: ').strip()
if not choice:continue
if choice == '':
buy() if __name__ == '__main__':
run()

read_ini.py

log/

all2.log

[ python ] 软件开发规范的更多相关文章

  1. python软件开发规范&分文件对于后期代码的高效管理

    根据本人的学习,按照理解整理和补充了python模块的相关知识,希望对于一些需要了解的python爱好者有帮助! 一.软件开发规范--分文件 当代码存在一个py文件中时: 1.不便于管理 (修改,增加 ...

  2. Python软件开发规范

    bin  整个程序的执行路口    start.py conf 配置文件     setting.py lib   库  模块与包    common.py    sql.py core  核心逻辑  ...

  3. Python模块的导入以及软件开发规范

    Python文件的两种用途 1 . 当脚本直接使用,直接当脚本运行调用即可 def func(): print("from func1") func() 2 . 当做模块被导入使用 ...

  4. python 全栈开发,Day29(昨日作业讲解,模块搜索路径,编译python文件,包以及包的import和from,软件开发规范)

    一.昨日作业讲解 先来回顾一下昨日的内容 1.os模块 和操作系统交互 工作目录 文件夹 文件 操作系统命令 路径相关的 2.模块 最本质的区别 import会创建一个专属于模块的名字, 所有导入模块 ...

  5. Python 3 软件开发规范

    Python 3 软件开发规范 参考链接 http://www.cnblogs.com/linhaifeng/articles/6379069.html#_label14 对每个目录,文件介绍. #= ...

  6. python(37)- 软件开发规范

    软件开发规范 一.为什么要设计好目录结构? 1.可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等.从而非常快速的了解这个项目. 2 ...

  7. Python进阶(十)----软件开发规范, time模块, datatime模块,random模块,collection模块(python额外数据类型)

    Python进阶(十)----软件开发规范, time模块, datatime模块,random模块,collection模块(python额外数据类型) 一丶软件开发规范 六个目录: #### 对某 ...

  8. Python 入门之 软件开发规范

    Python 入门之 软件开发规范 1.软件开发规范 -- 分文件 (1)为什么使用软件开发规范: 当几百行--大几万行代码存在于一个py文件中时存在的问题: 不便于管理 修改 可读性差 加载速度慢 ...

  9. python中软件开发规范,模块,序列化随笔

    1.软件开发规范 首先: 当代码都存放在一个py文件中时会导致 1.不便于管理,修改,增加 2.可读性差 3.加载速度慢 划分文件1.启动文件(启动接口)--starts文件放bin文件里2.公共文件 ...

随机推荐

  1. CF44H Phone Number

    题意翻译 给你一个电话号码,根据这个号码生成一个新的号码.生成的规则就是 新号码的第一个数任意选(0-9), 然后之后的每一个新号码都按照以下规则生成: 第i个新号码=(第i-1个新号码+第i个老号码 ...

  2. 洛谷 P2233 [HNOI2002]公交车路线 解题报告

    P2233 [HNOI2002]公交车路线 题目背景 在长沙城新建的环城公路上一共有8个公交站,分别为A.B.C.D.E.F.G.H.公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另 ...

  3. Java考试题之三

    QUESTION 46Given:11. public class Test {12. public static void main(String [] args) {13. int x = 5;1 ...

  4. 形态学及其他集合运算(Morphological and Other Set Operations)

    摘    要:本实验主要实现形态学图像处理.主要验证图像集合的交并补运算.膨胀和腐蚀处理并利用图像集合的运算,实现形态学边界抽取算法并进行特征边界抽取.同时将膨胀和腐蚀扩展至灰度图像,编写函数实现灰度 ...

  5. git 删除远程仓库的命令

    # 删除远程仓库的命令: git branch -r -d origin/branch-name #其中这条命令必须执行,远程仓库才会删除 git push origin :branch-name # ...

  6. animatescroll.min.js ~~~~ jq滚动效果 优化target自定义方法

    $(".meun>div[name='meun_nav']>a").eq(1).on("click",function(){ $("bod ...

  7. socket--接受大数据

    一.简单ssh功能 1.1 实现功能 在前面的一篇博客中,我们已经实现了一个简单的类似Linux服务器ssh功能的小程序,可以输入系统命令来返回命令运行结果,今天我们也以此开始,看看socket如何来 ...

  8. [Java多线程]-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  9. OpenCV---直方图反向投影

    一:直方图反向投影的方法 二:二维直方图的表示 (一)直接显示 def hist2D_demo(image): hsv = cv.cvtColor(image,cv.COLOR_BGR2HSV) hi ...

  10. MySQL的连接类型

    首先我们来创建两个数据表: 结构: 我们用内连接来查看一下: select *  from test1 join  test2 on test1.aid=test2.aid; 由于内连接是等值连接,所 ...