day21 模块与包+软件开发目录规范
一、导入模块的两种方式
方式一 import + 模块 导入
优点:该模块内的名字不会和当前名称空间的名字冲突
缺点:在使用这个模块下的功能或者名字的时候需要加前缀显得麻烦
方式二 from + 模块 import 名字(模块中的函数或者变量名或者*(全部导入))
优点:代码精简,使用模块中功能不需要加前缀
缺点:容易和当前名称空间的名字混淆
ps 两种导入都可以在后面as起个别名,看具体需求
两种方式的导入模块都发生了三件事
- 产生了一个模块的名称空间
- 运行模块.py代码,讲运行产生的名字都丢到模块的名称空间中
第三件事就是两者的区别,from是直接把这个名字放在了当前名称空间,但是这个名字指向的值还是在模块中
#方式一导入模块,两个名称空间的变量互不影响,需要模块前缀的原因
import text2 #text2中的x=1
x=20
print(text2.x)
#方式二导入模块
from text2 import x,f2#f2的功能是修改全局的x=2,返回一个x
print(x)
#此时在全局中有一个名字x他的内存地址和text2中的x共同指向text2模块中1的内存地址
>>>1
x=3 #x和1的绑定关系解除,和3建立绑定关系
print(x)
>>>3
res = f2() #调用函数f2 获取x,此时获取的是text2中的x=1,将x=2并返回
print(res)
>>>2
print(x)#访问的是当前名称空间的x
>>>3
二、模块搜索的路径的优先级
优先级:
- 内存(内置模块)
- 硬盘:按照sys.path中存放的文件顺序依次查找导入的模块
import sys
print(sys.path)
['C:\\Users\\HZ\\PycharmProjects\\python实训\\笔记', 'C:\\Users\\HZ\\PycharmProjects\\python实训', 'C:\\Program Files\\JetBrains\\PyCharm 2019.3.4\\plugins\\python\\helpers\\pycharm_display', 'C:\\Users\\HZ\\AppData\\Local\\Programs\\Python\\Python37\\python37.zip', 'C:\\Users\\HZ\\AppData\\Local\\Programs\\Python\\Python37\\DLLs', 'C:\\Users\\HZ\\AppData\\Local\\Programs\\Python\\Python37\\lib', 'C:\\Users\\HZ\\AppData\\Local\\Programs\\Python\\Python37', 'C:\\Users\\HZ\\PycharmProjects\\python实训\\venv', 'C:\\Users\\HZ\\PycharmProjects\\python实训\\venv\\lib\\site-packages', 'C:\\Users\\HZ\\PycharmProjects\\python实训\\venv\\lib\\site-packages\\setuptools-39.1.0-py3.7.egg', 'C:\\Users\\HZ\\PycharmProjects\\python实训\\venv\\lib\\site-packages\\pip-10.0.1-py3.7.egg', 'C:\\Program Files\\JetBrains\\PyCharm 2019.3.4\\plugins\\python\\helpers\\pycharm_matplotlib_backend']
通过实验验证加载顺序
import sys
import time
import text2#此时已经导入内存
text2.say()
time.sleep(5)#我们把text2文件删除
import text2
text2.say()#发现还是能执行,说明加载顺序在内存中优先
可以通过sys.path路径的添加,导入其他文件内的模块
import sys
#sys.modules查看已经加载到内存的模块,不导入其他模块时加载的都是内置模块
sys.path.append(r"C:\Users\HZ\PycharmProjects\python实训\笔记\day9")
import day9
print(day9.x)
三、循环导入
上节课我们讲了函数的递归,循环导入的做法也类似,但是我们在写程序的时候千万不能出现循环导入,如果出现了这样的屎一样的代码,就用以下两种“屎上雕花”
# 方案一:导入语句放到最后,保证在导入时,所有名字都已经加载过
# 文件:m1.py
print('正在导入m1')
x='m1'
from m2 import y
# 文件:m2.py
print('正在导入m2')
y='m2'
from m1 import x
# 文件:run.py内容如下,执行该文件,可以正常使用
import m1
print(m1.x)
print(m1.y)
# 方案二:导入语句放到函数中,只有在调用函数时才会执行其内部代码
# 文件:m1.py
print('正在导入m1')
def f1():
from m2 import y
print(x,y)
x = 'm1'
# 文件:m2.py
print('正在导入m2')
def f2():
from m1 import x
print(x,y)
y = 'm2'
# 文件:run.py内容如下,执行该文件,可以正常使用
import m1
m1.f1()
四、区分py文件的两种用途
py文件有两种用途,一种是作为程序运行,一种是作为模块导入。
所以每个文件都有可能作为两种用途来使用,我们可以用代码区分
#foo.py
...
if __name__ == '__main__':
foo.py被当做脚本执行时运行的代码
else:
foo.py被当做模块导入时运行的代码
五、编写一个规范的模板
我们在编写程序的时候,要知道这个代码不仅是给自己看的也要给别人看的,所有要有可读性和易维护性,我们就要对代码中的一些功能加以解释,通常以一个统一的规范编写
"The module is used to..." #模块的文档描述
import sys #导入模块
x=1 #定义全局变量,如果非必须,则最好使用局部变量,这样可以提高代码的易维护性,并且可以节省内存提高性能
class Foo: #定义类,并写好类的注释
'Class Foo is used to...'
pass
def test(): #定义函数,并写好函数的注释
'Function test is used to…'
pass
if __name__ == '__main__': #主程序
test() #在被当做脚本执行时,执行此处的代码
五、包
1 什么是包
包就是一个包含有--init--.py文件的文件夹
2 为什么要有包
包的本质是模块的一种形式,包是用来被当做模块导入的
#1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
#2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模
3 包的相关使用
1、执行包下的__init__.py文件
2、产生一个新的名称空间用于存放__init__.py执行过程中产生的名字
3、在当前执行文件所在的名称空间中得到一个名字pool,该名字指向__init__.py的名称空间,例如pool.xxx和pool.yyy中的xxx和yyy都是来自于pool下的__init__.py,也就是说导入包时并不会导入包下所有的子模块与子包
导包的两种情景
3.1 在当前文件内导该文件内的包
#导入同级目录下包aaa内的f2模块
#导入包aaa的同时会执行__init__.py文件
from aaa import f2
f2.func2()
3.2 在当前文件内导该文件外的包
import sys,os
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
#导入上层目录下的aaa,我们需要把此时运行的文件的环境变量扩展到上层目录 不然无法找到aaa
from aaa import f1
f1.func1()
六、软件开发的目录规范
为了提高程序的可读性与可维护性,我们应该为软件设计良好的目录结构,这与规范的编码风格同等重要。软件的目录规范并无硬性标准,只要清晰可读即可,假设你的软件名为foo,笔者推荐目录结构如下
Foo/
|-- core/
| |-- core.py
|
|-- api/
| |-- api.py
|
|-- db/
| |-- db_handle.py
|
|-- lib/
| |-- common.py
|
|-- conf/
| |-- settings.py
|
|-- run.py
|-- setup.py
|-- requirements.txt
|-- README
简要解释一下:
• core/: 存放业务逻辑相关代码
• api/: 存放接口文件,接口主要用于为业务逻辑提供数据操作。
• db/: 存放操作数据库相关文件,主要用于与数据库交互
• lib/: 存放程序中常用的自定义模块
• conf/: 存放配置文件
• run.py: 程序的启动文件,一般放在项目的根目录下,因为在运行时会默认将运行文件所在的文件夹作为sys.path的第一个路径,这样就省去了处理环境变量的步骤
• setup.py: 安装、部署、打包的脚本。
• requirements.txt: 存放软件依赖的外部Python包列表。
• README: 项目说明文件。
除此之外,有一些方案给出了更加多的内容,比如LICENSE.txt,ChangeLog.txt文件等,主要是在项目需要开源时才会用到,请读者自行查阅。
关于README的内容,这个应该是每个项目都应该有的一个文件,目的是能简要描述该项目的信息,让读者快速了解这个项目。它需要说明以下几个事项:
1、软件定位,软件的基本功能;
2、运行代码的方法: 安装环境、启动命令等;
3、简要的使用说明;
4、代码目录结构说明,更详细点可以说明软件的基本原理;
5、常见问题说明。
一般来说,用setup.py来管理代码的打包、安装、部署问题。业界标准的写法是用Python流行的打包工具setuptools来管理这些事情,这种方式普遍应用于开源项目中。不过这里的核心思想不是用标准化的工具来解决这些问题,而是说,一个项目一定要有一个安装部署工具,能快速便捷的在一台新机器上将环境装好、代码部署好和将程序运行起来。
requirements.txt文件的存在是为了方便开发者维护软件的依赖库。我们需要将开发过程中依赖库的信息添加进该文件中,避免在 setup.py安装依赖时漏掉软件包,同时也方便了使用者明确项目引用了哪些Python包。
这个文件的格式是每一行包含一个包依赖的说明,通常是flask>=0.10这种格式,要求是这个格式能被pip识别,这样就可以简单的通过 pip install -r requirements.txt来把所有Python依赖库都装好了,具体格式参照https://pip.readthedocs.io/en/1.1/requirements.html
day21 模块与包+软件开发目录规范的更多相关文章
- Python模块:Re模块、附软件开发目录规范
Re模块:(正则表达式) 正则表达式就是字符串的匹配规则 正则表达式在多数编程语言里都有相应的支持,Python里面对应的模块时re 常用的表达式规则:(都需要记住) “ . ” # 默认匹配除 ...
- py 包和模块,软件开发目录规范
目录 py 包和模块,软件开发目录规范 什么是包? 什么是模块? 软件开发目录规范 py 包和模块,软件开发目录规范 什么是包? 包指的是内部包__init__.py的文件夹 包的作用: 存放模块,包 ...
- python模块导入-软件开发目录规范-01
模块 模块的基本概念 模块: # 一系列功能的结合体 模块的三种来源 """ 模块的三种来源 1.python解释器内置的模块(os.sys....) 2.第三方的别人写 ...
- python基础语法10 函数递归,模块,软件开发目录规范
函数递归: 函数递归指的是重复 “直接调用或间接调用” 函数本身, 这是一种函数嵌套调用的表现形式. 直接调用: 指的是在函数内置,直接调用函数本身. 间接调用: 两个函数之间相互调用间接造成递归. ...
- python 之 软件开发目录规范 、logging模块
6.4 软件开发目录规范 软件(例如:ATM)目录应该包含: 文件名 存放 备注 bin start.py,用于起动程序 core src.py,程序核心功能代码 conf settings. ...
- Python 浅谈编程规范和软件开发目录规范的重要性
最近参加了一个比赛,然后看到队友编程的代码,我觉得真的是觉得注释和命名规范的重要性了,因为几乎每个字符都要咨询他,用老师的话来说,这就是命名不规范的后续反应.所以此时的我意识到写一篇关于注释程序的重要 ...
- python浅谈编程规范和软件开发目录规范的重要性
前言 我们这些初学者,目前要做的就是遵守代码规范,这是最基本的,而且每个团队的规范可能还不一样,以后工作了,尽可能和团队保持一致,目前初学者就按照官方的要求即可 新人进入一个企业,不会接触到核心的架构 ...
- Python记录13:软件开发目录规范
软件开发目录规范 开发一个软件,一个工程项目,一般应该具备以下的几个基本的文件夹和模块,当然,这并不是一成不变的,根据项目的不同会有一定的差异,不过作为一个入门级的新手,建议暂时按照以下的规范编写: ...
- 软件开发目录规范 ATM框架构建
软件开发的目录规范 建立文件夹 为了提高程序的可读性与可维护性,我们应该为软件设计良好的目录结构,这与规范的编码风格同等重要.软件的目录规范并无硬性标准,只要清晰可读即可 以ATM购物车项目为例: 首 ...
随机推荐
- MySQL进阶篇(02):索引体系划分,B-Tree结构说明
本文源码:GitHub·点这里 || GitEE·点这里 一.索引简介 1.基本概念 首先要明确索引是什么:索引是一种数据结构,数据结构是计算机存储.组织数据的方式,是指相互之间存在一种或多种特定关系 ...
- HDU-4341 Gold miner 题解
题目大意 黄金矿工的游戏,不过每个金块可以看做是质点,没有大小,给出每个金块的坐标.抓取所花费的时间(包括返回的时间),以及价值,其中有一些金块可能会共线.求在规定时间内所获得的最大价值. 样例 样例 ...
- oracle 锁表解决方式
/*查看被锁住的存储过程*/ SELECT * FROM V$DB_OBJECT_CACHE WHERE OWNER = 'APPADMIN' AND LOCKS != '0'; SELECT * F ...
- Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算
前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...
- 别人开发三年30k,而我才12K,看完他面试前狂刷的面试题,我惊了
朋友做Java开发三年多的时间了,在老东家勤勤恳恳工作了三年多,工资也就是从刚开始的8K涨到了12K,天天给我吐槽他的工资低.2019年中下旬开始就一直在各种地方找资源,刷面试题,想要“骑驴找马”,所 ...
- SpringCloud Alibaba (一):序言
为什么要转用SpringCloud Alibaba? Spring Cloud Netflix项目进入维护模式 在2018年底时,Netflix宣布Hystrix进入维护模式.自2016年以来,Rib ...
- 华为海思搞定4K60fps!Vmate掌上云台相机国内首发
目录 Snoppa Vmate Snoppa Vmate Snoppa Vmate是一款掌上型的高性能4K摄像机,集成了微型机械三轴增稳云台,一体化机身集成可操控式触摸屏,既可以独立使用,也可以无线连 ...
- mysql面试题总结
Mysql中的myisam与innodb的区别? InnoDB存储引擎的四大特性? 什么是事务? 数据库事务的四大特性? 不考虑事务的隔离性,会发生几种问题? MySQL数据库提供的四种隔离级别? 有 ...
- jquery 李南江老师jquery和ajax视频教程
链接:https://pan.baidu.com/s/11QF97RLg1aW9bf6o-CdHvQ 密码:qfer https://www.bilibili.com/video/av22807707 ...
- 搞定ReentrantReadWriteLock 几道小小数学题就够了
| 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it ...