day20——规范化目录
day20
为什么要有规范化目录
- 可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。
- 可维护性高: 定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。
变量:静态路径。变量
代码分类:
加载快
可读性高
查询修改都简单
分析规范化目录
所有文件都在blog文件夹下
1、start.py 文件
在bin文件夹下
项目启动文件。你的项目需要有专门的文件启动,而不是在你的核心逻辑部分进行启动的,有人对这个可能不太理解,我为什么还要设置一个单独的启动文件呢?你看你生活中使用的所有电器基本都一个单独的启动按钮,汽车,热水器,电视,等等等等,那么为什么他们会单独设置一个启动按钮,而不是在一堆线路板或者内部随便找一个地方开启呢? 目的就是放在显眼的位置,方便开启。你想想你的项目这么多py文件,如果src文件也有很多,那么到底哪个文件启动整个项目,你还得一个一个去寻找,太麻烦了,这样我把它单独拿出来,就是方便开启整个项目。
import sys
import os
# sys.path.append(r'D:\lnh.python\py project\teaching_show\blog')
# print(os.path.dirname(__file__))
# 获取本文件的绝对路径 # D:/lnh.python/py project/teaching_show/blog/bin
# print(os.path.dirname(os.path.dirname(__file__)))
# 获取父级目录也就是blog的绝对路径 # D:/lnh.python/py project/teaching_show/blog
BATH_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BATH_DIR)
from core.src import run
if __name__ == '__main__':
run()
2、settings.py文件
在conf文件夹下
配置文件,就是放置一些项目中需要的静态参数,比如文件路径,数据库配置,软件的默认设置等等
3、src.py 主逻辑核心逻辑文件
在core文件夹下
这个文件主要存放的就是核心逻辑功能,你看你需要进行选择的这些核心功能函数,都应该放在这个文件中。
4、类似于register文件
在db文件夹下
用户信息,数据相关,多个文件,这个文件文件名不固定,register只是我们项目中用到的注册表,但是这种文件就是存储数据的文件,类似于文本数据库,那么我们一些项目中的数据有的是从数据库中获取的,有些数据就是这种文本数据库中获取的,总之,你的项目中有时会遇到将一些数据存储在文件中,与程序交互的情况,所以我们要单独设置这样的文件。
5、common.py 公共组件部分
在lib文件夹下
公共组件文件,这里面放置一些我们常用的公共组件函数,并不是我们核心逻辑的函数,而更像是服务于整个程序中的公用的插件,程序中需要即调用。比如我们程序中的装饰器auth,有些函数是需要这个装饰器认证的,但是有一些是不需要这个装饰器认证的,它既是何处需要何处调用即可。比如还有密码加密功能,序列化功能,日志功能等这些功能都可以放在这里。
6、logging日志文件——access.log
在log文件夹下
记录用户的访问次数,转账,取钱,充钱等等,log文件顾名思义就是存储log日志的文件。日志我们一会就会讲到,日志主要是供开发人员使用。比如你项目中出现一些bug问题,比如开发人员对服务器做的一些操作都会记录到日志中,以便开发者浏览,查询。
7、README
这个我觉得是每个项目都应该有的一个文件,目的是能简要描述该项目的信息,让读者快速了解这个项目。
它需要说明以下几个事项:
- 软件定位,软件的基本功能。
- 运行代码的方法: 安装环境、启动命令等。
- 简要的使用说明。
- 代码目录结构说明,更详细点可以说明软件的基本原理。
- 常见问题说明。
我觉得有以上几点是比较好的一个README
。在软件开发初期,由于开发过程中以上内容可能不明确或者发生变化,并不是一定要在一开始就将所有信息都补全。但是在项目完结的时候,是需要撰写这样的一个文档的。
可以参考Redis源码中Readme的写法,这里面简洁但是清晰的描述了Redis功能和源码结构。
博客园代码演示
原代码
status_dic = {
'username': None,
'status': False,
}
flag = True
REGISTER_PATH = r'F:\s24\day20\register'
def login():
i = 0
with open(REGISTER_PATH, encoding='utf-8') as f1:
dic = {i.strip().split('|')[0]: i.strip().split('|')[1] for i in f1}
while i < 3:
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
if username in dic and dic[username] == password:
print('登录成功')
status_dic['username'] = username
status_dic['status'] = True
return True
else:
print('用户名密码错误,请重新登录')
i += 1
def register():
with open(REGISTER_PATH, encoding='utf-8') as f1:
dic = {i.strip().split('|')[0]: i.strip().split('|')[1] for i in f1}
while 1:
print('\033[1;45m 欢迎来到注册页面 \033[0m')
username = input('请输入用户名:').strip()
if not username.isalnum():
print('\033[1;31;0m 用户名有非法字符,请重新输入 \033[0m')
continue
if username in dic:
print('\033[1;31;0m 用户名已经存在,请重新输入 \033[0m')
continue
password = input('请输入密码:').strip()
if 6 <= len(password) <= 14:
with open(REGISTER_PATH, encoding='utf-8', mode='a') as f1:
f1.write(f'\n{username}|{password}')
status_dic['username'] = str(username)
status_dic['status'] = True
print('\033[1;32;0m 恭喜您,注册成功!已帮您成功登录~ \033[0m')
return True
else:
print('\033[1;31;0m 密码长度超出范围,请重新输入 \033[0m')
def auth(func):
def inner(*args, **kwargs):
if status_dic['status']:
ret = func(*args, **kwargs)
return ret
else:
print('\033[1;31;0m 请先进行登录 \033[0m')
if login():
ret = func(*args, **kwargs)
return ret
return inner
@auth
def article():
print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问文章页面\033[0m')
@auth
def diary():
print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问日记页面\033[0m')
@auth
def comment():
print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问评论页面\033[0m')
@auth
def enshrine():
print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问收藏页面\033[0m')
def login_out():
status_dic['username'] = None
status_dic['status'] = False
print('\033[1;32;0m 注销成功 \033[0m')
def exit_program():
global flag
flag = False
return flag
choice_dict = {
1: login,
2: register,
3: article,
4: diary,
5: comment,
6: enshrine,
7: login_out,
8: exit_program,
}
def run():
while flag:
print('''
欢迎来到博客园首页
1:请登录
2:请注册
3:文章页面
4:日记页面
5:评论页面
6:收藏页面
7:注销
8:退出程序''')
choice = input('请输入您选择的序号:').strip()
if choice.isdigit():
choice = int(choice)
if 0 < choice <= len(choice_dict):
choice_dict[choice]()
else:
print('\033[1;31;0m 您输入的超出范围,请重新输入 \033[0m')
else:
print('\033[1;31;0m 您您输入的选项有非法字符,请重新输入 \033[0m')
规范化目录
blog
bin-starts.py
# run() # 找不到名字
# 找到src.py文件的run名字
# from src import run
# run()
# sys.path 到底是什么?
# import time
# import t1
# import sys
# t1.func()
'''
sys模块内置模块,文件运行时,sys内置模块就会将一些模块 自动 加载到内存. 内置模块. time,json pickle等等.以及当前目录的.
如何引用到一个模块最本质的原因在于这个模块名称空间在不在内存.
如果直接引用不到一个模块,他必定不是内置或者当前目录下的py文件.
所以,我们要手动将其添加到内存.
sys.path.append()就是手动的将一些模块添加到内存,添加完毕之后,就可以直接引用了.
'''
# import sys
# # 版本二: 繁琐,我要将整个项目作为根目录,添加到内存中.
# sys.path.append(r'F:\s24\day20\模拟博客园代码\blog\core')
# sys.path.append(r'F:\s24\day20\模拟博客园代码\blog\conf')
# sys.path.append(r'F:\s24\day20\模拟博客园代码\blog\db')
# from src import run
# run()
# 版本三: 你把项目路径写死了,所有的开发人员如果共同开发这个项目,必须都得按照这个目录结构去构建.
# import sys
# sys.path.append(r'F:\s24\day20\模拟博客园代码\blog')
# from core.src import run
# run()
# 版本四:
import sys
import os
# print(__file__)
# print(os.path.dirname(os.path.dirname(__file__)))
# sys.path.append(r'F:\s24\day20\模拟博客园代码\blog')
# from core.src import run
# run()
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_PATH)
from core.src import run
if __name__ == '__main__':
run()
conf-settings.py
import sys
import os
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
REGISTER_PATH = os.path.join(BASE_PATH, 'db', 'register')
core-src.py
from conf import settings
from lib import common
status_dic = {
'username': None,
'status': False,
}
flag = True
def login():
i = 0
with open(settings.REGISTER_PATH, encoding='utf-8') as f1:
dic = {i.strip().split('|')[0]: i.strip().split('|')[1] for i in f1}
while i < 3:
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
if username in dic and dic[username] == password:
print('登录成功')
status_dic['username'] = username
status_dic['status'] = True
return True
else:
print('用户名密码错误,请重新登录')
i += 1
def register():
with open(settings.REGISTER_PATH, encoding='utf-8') as f1:
dic = {i.strip().split('|')[0]: i.strip().split('|')[1] for i in f1}
while 1:
print('\033[1;45m 欢迎来到注册页面 \033[0m')
username = input('请输入用户名:').strip()
if not username.isalnum():
print('\033[1;31;0m 用户名有非法字符,请重新输入 \033[0m')
continue
if username in dic:
print('\033[1;31;0m 用户名已经存在,请重新输入 \033[0m')
continue
password = input('请输入密码:').strip()
if 6 <= len(password) <= 14:
with open(settings.REGISTER_PATH, encoding='utf-8', mode='a') as f1:
f1.write(f'\n{username}|{password}')
status_dic['username'] = str(username)
status_dic['status'] = True
print('\033[1;32;0m 恭喜您,注册成功!已帮您成功登录~ \033[0m')
return True
else:
print('\033[1;31;0m 密码长度超出范围,请重新输入 \033[0m')
@common.auth
def article():
print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问文章页面\033[0m')
@common.auth
def diary():
print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问日记页面\033[0m')
@common.auth
def comment():
print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问评论页面\033[0m')
@common.auth
def enshrine():
print(f'\033[1;32;0m 欢迎{status_dic["username"]}访问收藏页面\033[0m')
def login_out():
status_dic['username'] = None
status_dic['status'] = False
print('\033[1;32;0m 注销成功 \033[0m')
def exit_program():
global flag
flag = False
return flag
choice_dict = {
1: login,
2: register,
3: article,
4: diary,
5: comment,
6: enshrine,
7: login_out,
8: exit_program,
}
def run():
while flag:
print('''
欢迎来到博客园首页
1:请登录
2:请注册
3:文章页面
4:日记页面
5:评论页面
6:收藏页面
7:注销
8:退出程序''')
choice = input('请输入您选择的序号:').strip()
if choice.isdigit():
choice = int(choice)
if 0 < choice <= len(choice_dict):
choice_dict[choice]()
else:
print('\033[1;31;0m 您输入的超出范围,请重新输入 \033[0m')
else:
print('\033[1;31;0m 您您输入的选项有非法字符,请重新输入 \033[0m')
db-register
liye|liyedsb
meet|baoyuandsb
log-access.log
README
说明书
day20——规范化目录的更多相关文章
- python 20 规范化目录
目录 规范化目录 1. 划归固定的路径: 2. 划分文件 2.1 seetings 配置文件 2.2 common 公共组件文件 2.3 src 主文件 2.4 starts 项目启动文件 2.5 类 ...
- Python开发之规范化目录
13.规范化目录 规范目录优点: 可读性高 加载快 查询修改简 规范化目录结构 (1) start.py文件:首要配置启动文件,运行run()就可以执行项目 #start import sys imp ...
- Maven 的这 7 个问题你思考过没有?
在如今的互联网项目开发当中,特别是Java领域,可以说Maven随处可见.Maven的仓库管理.依赖管理.继承和聚合等特性为项目的构建提供了一整套完善的解决方案,可以说如果你搞不懂Maven,那么一个 ...
- python之函数篇3
一:函数的定义 1)函数的简单使用,无参函数 def f1(): # 定义函数指定函数名 print("hello") # 指定功能 f1() # 调用函数,才能执行函数体里面的功 ...
- rsync+sersync多线程实时同步
一.sersync优点 1)使用c++编写,对linux系统文件产生的临时文件和重复文件操作会进行过滤,在结合rsync同步的时候,会减少运行时消耗的本地及网络资源,因此速度更快. 2)相比较inot ...
- Maven 虐我千百遍,我待 Maven 如初恋
前言 在如今的互联网项目开发当中,特别是Java领域,可以说Maven随处可见.Maven的仓库管理.依赖管理.继承和聚合等特性为项目的构建提供了一整套完善的解决方案,可以说如果你搞不懂Maven,那 ...
- 百万年薪python之路 -- 软件的开发规范
一. 软件的开发规范 什么是开发规范?为什么要有开发规范呢? 你现在包括之前写的一些程序,所谓的'项目',都是在一个py文件下完成的,代码量撑死也就几百行,你认为没问题,挺好.但是真正的后端开发的项目 ...
- 3年java开发面试BAT,你必须彻底搞定Maven!
前言 现在的Java项目中,Maven随处可见. Maven的仓库管理.依赖管理.继承和聚合等特性为项目的构建提供了一整套完善的解决方案,如果你搞不懂Maven,那么一个多模块的项目足以让你头疼,依赖 ...
- python27期day16:序列化、json、pickle、hashlib、collections、软件开发规范、作业。
序列化模块:什么是序列化呢? 序列化的本质就是将一种数据结构(如字典.列表)等转换成一个特殊的序列(字符串或者bytes)的过程就叫做序列化.将这个字典直接写入文件是不可以的,必须转化成字符串的形式, ...
随机推荐
- python中序列的操作
Python中的序列操作 可变对象:列表.字典.集合 不可变对象:数值.字符串.元组.forzenset 1.序列的通用操作 (1)测试元素是否存在 x in S和x not in S,返回True或 ...
- H5如何实现关闭当前页面,跳转到新页面?
小程序有此功能的跳转方法. 那么H5如何实现该功能? 很简单. location.replace('new.html') 这个方法可以实现 关闭当前页面,跳转到新页面 的效果. 而 windo ...
- Debian 9 安装 libsodium
到这里查看最新的版本号.如现在最新的版本号为1.0.18.下面均以该版本为例. 下载.编译和安装: wget https://download.libsodium.org/libsodium/rele ...
- Hdu 5093 Battle Ship
每个海面要么放要么不放,因此可以用二分图匹配, 考虑把同一行内的能互相看到的点放到一个行块里,同一列内能看到的点放到一个列块里,然后每一个行块都可以和该行块里所有海面的列块连边,选了这个行块,就必须选 ...
- 微信小程序与云开发
微信小程序基础概念 小程序云开发的三大基础能力:云数据库.云函数.云存储 Java.NodeJS.JavaScript.HTML5.CSS3.VueJs.ReactJs.前端工程化.前端架构 小程序开 ...
- kings(骑士)解题报告
kings(骑士) Time Limit5000 ms Memory Limit131072 KBytes Description 用字符矩阵来表示一个8x8的棋盘,'.'表示是空格,'P'表示 ...
- mysql 字段添加以及删除
mysql> select * from user; +------+-----------+-----------+ | id | name | address | +------+----- ...
- TP5验证码上传阿里云万网虚拟主机后,验证码不显示的解决办法
TP5不显示验证码 清除缓冲区就应该可以了,今天我刚好也遇到了,解决的办法是在vendor/topthink/think-captcha/CaptchaController.php中加上这个ob_cl ...
- 2019暑假Java学习笔记(三)
目录 面向对象 对象 构造方法 引用与对象实例 static final 封装 this 继承 super 方法重载与重写 多态 抽象类 接口 内部类 成员内部类 静态内部类 局部内部类 匿名内部类 ...
- Java8新特性 (一)Lambda
目录 一.Lambda介绍 二.Lambda用法实例 三.Lambda变量作用域 前言: 这两天彻底的复习了一遍Java8的各种新特性,趁着热乎劲,把知识点整理成博客的形式保存一下. 一.Lambda ...