在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. 如何使用火狐下的两款接口测试工具RESTClient和HttpRequester发送post请求

    Chrome下有著名的Postman,那火狐也有它的左膀右臂,那就是RESTClient和HttpRequester.这两款工具都是火狐的插件,主要用来模拟发送HTTP请求,HTTP请求最常用的两种方 ...

  2. 二次封装bootstrap-table及功能优化

    /** * 设置bootstrat-table * @param params */ function setBootstrapTable (target, params) { // 默认设置表格内容 ...

  3. Xml中SelectSingleNode方法,xpath查找某节点用法

    Xml中SelectSingleNode方法,xpath查找某节点用法 最常见的XML数据类型有:Element, Attribute,Comment, Text. Element, 指形如<N ...

  4. 使用 openssl 生成证书(转)

    一.openssl 简介 openssl 是目前最流行的 SSL 密码库工具,其提供了一个通用.健壮.功能完备的工具套件,用以支持SSL/TLS 协议的实现.官网:https://www.openss ...

  5. webpack 4.x使用总结

    1.webpack 全局安装 npm install -g webpack 2.创建项目 比如文件夹是webpackdemo cd到webpackdemo文件夹下,执行: npm init 和 npm ...

  6. 2017北京国庆刷题Day3 morning

    期望得分:100+60+0=160 实际得分:100+30+0=130 考场上用的哈希 #include<cstdio> #include<cstring> #include& ...

  7. HDU 1812 polya 大数

    由于反射的存在,分奇偶讨论其置换的循环节数量,大数用JAVA就好了. import java.math.*; import java.util.*; public class Main{ public ...

  8. 816C. Karen and Game 贪心

    LINK 题意:给出n*m的矩阵图,现有对行或对列上的数减1的操作,问最少几步使所有数变为0,无解输出-1 思路:贪心暴力即可.先操作行和先操作列结果可能不同注意比较. /** @Date : 201 ...

  9. (转)使用Excel批量给数据添加单引号和逗号

    在使用PLSQL连接oracle数据库处理数据的过程中,常用的操作是通过ID查询出数据,ID需要附上单引号,如果查询的ID为一条或者几条,我们手动添加即可,但是如果是几百条.几千条的话,就需要使用一些 ...

  10. layer弹窗的跳转功能

    1,本弹窗直接跳转父页面: @if(session('message')) <script> window.parent.location.reload(); //刷新父页面 var in ...