目录结构组织方式

简要解释一下:

  • bin/: 存放项目的一些可执行文件,当然你可以起名script/之类的也行。
  • luffy/: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/存放单元测试代码; (3) 程序的入口最好命名为main.py。
  • docs/: 存放一些文档。
  • core/:存放核心代码
  • conf/:存放配置
  • db/:存放数据
  • setup.py/: 安装、部署、打包的脚本。
  • lib/:存放自定义的模块与包
  • requirements.txt: 存放软件依赖的外部Python包列表。
  • README: 项目说明文件。

关于README的内容

这个我觉得是每个项目都应该有的一个文件,目的是能简要描述该项目的信息,让读者快速了解这个项目。

它需要说明以下几个事项:

  1. 软件定位,软件的基本功能。
  2. 运行代码的方法: 安装环境、启动命令等。
  3. 简要的使用说明。
  4. 代码目录结构说明,更详细点可以说明软件的基本原理。
  5. 常见问题说明。
  6. 例子https://github.com/pallets/flask/blob/master/README.rst

关于requirements.txt和setup.py

setup.py

一般来说,用setup.py来管理代码的打包、安装、部署问题。业界标准的写法是用Python流行的打包工具setuptools来管理这些事情。

这种方式普遍应用于开源项目中。不过这里的核心思想不是用标准化的工具来解决这些问题,而是说,一个项目一定要有一个安装部署工具,

能快速便捷的在一台新机器上将环境装好、代码部署好和将程序运行起来。

setup.py可以将这些事情自动化起来,提高效率、减少出错的概率。"复杂的东西自动化,能自动化的东西一定要自动化。"是一个非常好的习惯。

setuptools的文档比较庞大,刚接触的话,可能不太好找到切入点。学习技术的方式就是看他人是怎么用的,可以参考一下Python的一个Web框架,

flask是如何写的: setup.py当然,简单点自己写个安装脚本(deploy.sh)替代setup.py也未尝不可

requirements.txt

这个文件存在的目的是:

  1. 方便开发者维护软件的包依赖。将开发过程中新增的包添加进这个列表中,避免在 setup.py 安装依赖时漏掉软件包。
  2. 方便读者明确项目使用了哪些Python包。

这个文件的格式是每一行包含一个包依赖的说明,通常是flask>=0.10这种格式,要求是这个格式能被pip识别,这样就可以简单的通过 pip install -r requirements.txt来把所有Python包依赖都装好了。具体格式说明: 点这里

生成requirements.txt

项目代码举例

  1. #=============>bin目录:存放执行脚本
  2. #start.py
  3. import sys,os
  4.  
  5. BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  6. sys.path.append(BASE_DIR)
  7.  
  8. from core import core
  9. from conf import my_log_settings
  10.  
  11. if __name__ == '__main__':
  12. my_log_settings.load_my_logging_cfg()
  13. core.run()
  14.  
  15. #=============>conf目录:存放配置文件
  16. #config.ini
  17. [DEFAULT]
  18. user_timeout = 1000
  19.  
  20. [x]
  21. password = 123
  22. money = 10000000
  23.  
  24. [y]
  25. password = 123456
  26. money=1000
  27.  
  28. [z]
  29. password = qwe123
  30. money=10
  31.  
  32. #settings.py
  33. import os
  34. config_path=r'%s\%s' %(os.path.dirname(os.path.abspath(__file__)),'config.ini')
  35. user_timeout=10
  36. user_db_path=r'%s\%s' %(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),\
  37. 'db')
  38.  
  39. #my_log_settings.py
  40. """
  41. logging配置
  42. """
  43.  
  44. import os
  45. import logging.config
  46.  
  47. # 定义三种日志输出格式 开始
  48.  
  49. standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
  50. '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
  51.  
  52. simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
  53.  
  54. id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
  55.  
  56. # 定义日志输出格式 结束
  57.  
  58. logfile_dir = r'%s\log' %os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # log文件的目录
  59.  
  60. logfile_name = 'all2.log' # log文件名
  61.  
  62. # 如果不存在定义的日志目录就创建一个
  63. if not os.path.isdir(logfile_dir):
  64. os.mkdir(logfile_dir)
  65.  
  66. # log文件的全路径
  67. logfile_path = os.path.join(logfile_dir, logfile_name)
  68.  
  69. # log配置字典
  70. LOGGING_DIC = {
  71. 'version': 1,
  72. 'disable_existing_loggers': False,
  73. 'formatters': {
  74. 'standard': {
  75. 'format': standard_format
  76. },
  77. 'simple': {
  78. 'format': simple_format
  79. },
  80. },
  81. 'filters': {},
  82. 'handlers': {
  83. #打印到终端的日志
  84. 'console': {
  85. 'level': 'DEBUG',
  86. 'class': 'logging.StreamHandler', # 打印到屏幕
  87. 'formatter': 'simple'
  88. },
  89. #打印到文件的日志,收集info及以上的日志
  90. 'default': {
  91. 'level': 'DEBUG',
  92. 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
  93. 'formatter': 'standard',
  94. 'filename': logfile_path, # 日志文件
  95. 'maxBytes': 1024*1024*5, # 日志大小 5M
  96. 'backupCount': 5,
  97. 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
  98. },
  99. },
  100. 'loggers': {
  101. #logging.getLogger(__name__)拿到的logger配置
  102. '': {
  103. 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
  104. 'level': 'DEBUG',
  105. 'propagate': True, # 向上(更高level的logger)传递
  106. },
  107. },
  108. }
  109.  
  110. def load_my_logging_cfg():
  111. logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
  112. logger = logging.getLogger(__name__) # 生成一个log实例
  113. logger.info('It works!') # 记录该文件的运行状态
  114.  
  115. if __name__ == '__main__':
  116. load_my_logging_cfg()
  117.  
  118. #=============>core目录:存放核心逻辑
  119. #core.py
  120. import logging
  121. import time
  122. from conf import settings
  123. from lib import read_ini
  124. from conf import my_log_settings
  125.  
  126. # print(__name__)
  127. config = read_ini.read(settings.config_path)
  128. logger = my_log_settings.load_my_logging_cfg(__name__)
  129.  
  130. current_user={'user':None,'login_time':None,'timeout':int(settings.user_timeout)}
  131. def auth(func):
  132. def wrapper(*args,**kwargs):
  133. if current_user['user']:
  134. interval=time.time()-current_user['login_time']
  135. if interval < current_user['timeout']:
  136. return func(*args,**kwargs)
  137. name = input('name>>: ')
  138. password = input('password>>: ')
  139. if config.has_section(name):
  140. if password == config.get(name,'password'):
  141. logger.info('登录成功')
  142. current_user['user']=name
  143. current_user['login_time']=time.time()
  144. return func(*args,**kwargs)
  145. else:
  146. logger.error('登录失败')
  147. else:
  148. logger.error('用户名不存在')
  149.  
  150. return wrapper
  151.  
  152. @auth
  153. def buy():
  154. print('buy...')
  155.  
  156. @auth
  157. def run():
  158.  
  159. print('''
  160. 购物
  161. 查看余额
  162. 转账
  163. ''')
  164. while True:
  165. choice = input('>>: ').strip()
  166. if not choice:continue
  167. if choice == '':
  168. buy()
  169.  
  170. #=============>db目录:存放数据库文件
  171. #x_json
  172. #y_json
  173.  
  174. #=============>lib目录:存放自定义的模块与包
  175. #read_ini.py
  176. import configparser
  177. def read(config_file):
  178. config=configparser.ConfigParser()
  179. config.read(config_file)
  180. return config
  181.  
  182. #=============>log目录:存放日志
  183. #all.log
  184. [2018-04-20 00:19:48,587][MainThread:10840][task_id:__main__][my_logsettiing.py:75][INFO][It works!]
  185. [2018-04-20 00:28:29,387][MainThread:9492][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
  186. [2018-04-20 00:32:14,803][MainThread:15240][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
  187. [2018-04-20 00:39:30,564][MainThread:11216][task_id:__main__][my_log_settings.py:75][INFO][It works!]
  188. [2018-04-20 00:39:46,132][MainThread:11216][task_id:__main__][core.py:22][INFO][登录成功]
  189. [2018-04-20 00:41:27,929][MainThread:6644][task_id:core.core][my_log_settings.py:75][INFO][It works!]
  190. [2018-04-20 00:41:44,162][MainThread:8620][task_id:core.core][my_log_settings.py:75][INFO][It works!]
  191. [2018-04-20 00:41:44,163][MainThread:8620][task_id:__main__][my_log_settings.py:75][INFO][It works!]
  192. [2018-04-20 00:41:53,689][MainThread:8620][task_id:core.core][core.py:29][ERROR][用户名不存在]
  193. [2018-04-20 00:44:33,641][MainThread:14012][task_id:__main__][my_log_settings.py:75][INFO][It works!]
  194. [2018-04-20 00:44:42,086][MainThread:14012][task_id:__main__][core.py:22][INFO][登录成功]
  195. [2018-04-20 00:47:22,321][MainThread:9460][task_id:__main__][my_log_settings.py:75][INFO][It works!]
  196. [2018-04-20 00:47:25,847][MainThread:9460][task_id:__main__][core.py:29][ERROR][用户名不存在]
  197. [2018-04-20 00:51:58,265][MainThread:14784][task_id:core.core][my_log_settings.py:75][INFO][It works!]
  198. [2018-04-20 00:51:58,265][MainThread:14784][task_id:__main__][my_log_settings.py:75][INFO][It works!]
  199. [2018-04-20 00:52:14,703][MainThread:14784][task_id:core.core][core.py:22][INFO][登录成功]

Python项目代码结构的更多相关文章

  1. 正确地组织python项目的结构

    统一的项目结构 写了不少python项目后, 越来越认识到python项目结构重要性. 不管项目是否要开源, 是否要提交pypi, 项目结构的一致性带来的好处还有很多: 多人合作开发大家都有个基本的g ...

  2. python 项目目录结构

    目录组织方式 关于如何组织一个较好的Python工程目录结构,已经有一些得到了共识的目录结构.在Stackoverflow的这个问题上,能看到大家对Python目录结构的讨论. 这里面说的已经很好了, ...

  3. 【Learning Python】【第四章】Python代码结构(一)

    这一章的主旨在于介绍python的代码结构 缩进 在很多的编程语言中,一般{}用于控制代码块,比如以下的一段C代码 if(var <= 10) { printf("....." ...

  4. Python 项目结构

    Python 项目结构 实验准备 我们的实验项目名为 factorial. 12 $ mkdir factorial$ cd factorial/ 主代码 我们给将要创建的 Python 模块取名为 ...

  5. 【VIP视频网站项目】VIP视频网站项目v1.0.3版本发布啦(程序一键安装+电影后台自动抓取+代码结构调整)

    在线体验地址:http://vip.52tech.tech/ GIthub源码:https://github.com/xiugangzhang/vip.github.io 项目预览 主页面 登录页面 ...

  6. GitHub Python项目推荐|瓦力Devops开源项目代码部署平台持续部署

    GitHub Python项目推荐|walle - 瓦力 Devops开源项目代码部署平台 项目热度 标星(star):8418 (很不错的实用项目,大神作品,建议关注) 标星趋势 关注(watch) ...

  7. 使用PYTHON统计项目代码行数

    目录 一 使用PYTHON统计项目代码行数 二 应用实例 注:原创不易,转载请务必注明原作者和出处,感谢支持! 一 使用PYTHON统计项目代码行数 遇到一个非常小的需求:统计一个项目里头的各类源代码 ...

  8. 教你阅读Python开源项目代码

    为什么要阅读开源代码 阅读 Python 开源项目代码主要有如下三个原因: 在工作过程中遇到一些问题 Google 和 StackOverFlow 等网站找不到解决办法,只能去翻源码. 对某些项目或者 ...

  9. python项目实践一:即时标记

    转自:http://www.code123.cc/1317.html 这是<python基础教程>后面的实践,照着写写,一方面是来熟悉python的代码方式,另一方面是练习使用python ...

随机推荐

  1. python中assert详解

    assert基础 官方解释:"Assert statements are a convenient way to insert debugging assertions into a pro ...

  2. jquery全国省市区三级联动插件distpicker

    使用步骤: 1.引入js <script src="distpicker/jquery.min.js" type="text/javascript" ch ...

  3. FortiGate下视频会议等语音相关配置

    关闭老的基于会话的alg机制(即删除session-helper中的SIP条目) config system session-helper delete 13  #删除sip end

  4. 拉普拉斯平滑处理 Laplace Smoothing

    背景:为什么要做平滑处理? 零概率问题,就是在计算实例的概率时,如果某个量x,在观察样本库(训练集)中没有出现过,会导致整个实例的概率结果是0.在文本分类的问题中,当一个词语没有在训练样本中出现,该词 ...

  5. 【Android】异步加载布局探索

    最近在做的项目页面复杂导致布局嵌套多层,而且又使用了百分比布局(可能主要是这个原因)导致页面加载的时候主线程会被阻塞, 那要想减少主线程阻塞,一来就是简化布局,减轻LayoutInflater的负担, ...

  6. echart.js在vue中使用

    以前可能写过,懒得去翻了,再写一次 1,安装echarts   导入到页面 import echarts from 'echarts'; 2.在生命周期里面做初始化 data(){ return{ t ...

  7. idea打包含第三方依赖的jar包

    1.打开idea,打开java项目,选择file-->Project Structure,添加依赖的jar包 2.配置artfacts 点击ok,不需要做任何操作 点击jar,右键新建一个lib ...

  8. dom4j 操作总结

    在官网https://dom4j.github.io/下载最新的dom4j的jar包,以及配合xpath解析的http://central.maven.org/maven2/jaxen/jaxen/1 ...

  9. linux学习第十二天 (Linux就该这么学)找到一本不错的Linux电子书,附《Linux就该这么学》章节目录

    本书是由全国多名红帽架构师(RHCA)基于最新Linux系统共同编写的高质量Linux技术自学教程,极其适合用于Linux技术入门教程或讲课辅助教材,目前是国内最值得去读的Linux教材,也是最有价值 ...

  10. 实现一个jsp同时提交两个form到两个Servlet

    <%@ page contentType="text/html;charset=GBK" language="java"%> <html> ...