ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

模块、包、目录规范与模块编写规范

2022-09-13 13:34:41  阅读:202  来源: 互联网

标签:__ 文件 规范 导入 模块 import 编写 foo



模块、包、目录规范与模块编写规范

一、什么是模块?
模块分三大类
1、内置模块,python自带的
2、第三方模块,别人写的,发布到网上的,pip导入的那种
3、自定义的模块,自己写的一个py文件就是一个模块,,m.py文件,这个m就是一个模块
自己写的一个文件夹,也是这一个模块
文件名:foo.py 模块名foo
模块的4种形式:
1、使用python写的.py文件
2、已经被编译为共享库或者dll的c或者c++扩展
3、把一系列模块组织到一起的文件夹(注:文件夹下一定有一个__init__文件),读这个文件夹就是读这个文件
就是包,,pickage
4、使用c编写并链接到python解释器的内置模块

二、为什么要用模块?
1、内置与第三方模块可以拿来就用,不用再造轮子,可以极大的提升效率。
2、自定义的模块:可以将程序的各部分功能提取出来,放到一个模块中,供大家共享使用。
好处是减少了代码冗余,使程序组织结构更加清晰。

三、如何用?
1、import foo # 这里的run是foo.py的名字,是run
实际上就是导入这个foo.py文件
2、首次导入模块会发生三件事:
1、执行foo这个文件
2、运行foo.py这个文件,将这个文件产生的所有变量名字都丢到叫foo的名称空间。
3、在当前文件中产生一个名字叫foo,该名字的内存地址指向2中叫foo的名称空间。

3、 首次导入会发生这三件事,再次导入时,都是引用第一次导入的内容。不会重复执行代码。

4、引用:
强调1:指名道姓的问某一个模块要名字对应的值
如:import foo
foo.f1.() # 执行foo.py中的f1()
强调2:无论是查看还是引用,都是以原模块为准,与调用位置无关
也就是调用的都是原模块的设置与变量值。
5、导入模块格式
如下:
import time
import random
import os

不要这样import time, datetime, random, os, sys,,乱

6、导入模块规范
导入顺序:
1、python内置模块
2、第三方模块
3、程序员自定义模块

7、import。。。 as ... 可以为导入的模块起个别名
如:
import foo as f
调用: f.f1()

8、 函数是第一类对象,即函数可以当成变量去用,可被赋值,可当参数,可当成返回值,可当容器的元素
模块也是第一类对象

9、模块的命名
纯小写,与变量名的命名规则一致

10、导模块可以在开始位置导入,可以函数内部导入。

二、 一个python文件有几种用途? 执行py文件 与导入py文件有什么区别?
一个py文件有两种用途
1、被当作程序运行
2、被当作模块导入

二者的区别?
被当作程序运行的时候,运行完后,内存即回收
被当作模块导入时,只有在引用者关闭、del的时候,内存才被回收

每个py文件都内置了一个属性变量叫'__name__'。
当foo被运行时,'__name__'的值为'__main__'
当foo被当做模块导入时,'__name__'的值为”foo“

三、from...import ...
与import 有什么区别?
1、import导入模块,使用这个模块的功能时,必须加import前缀
random.randint()
优点:肯定不会与当前名称空间中的名字冲突
缺点:加了前缀,显得很麻烦

2、from...import...执行的时候,也发生三件事
运行foo
产生一个名称空间,放入产生的变量
在当前名称空间拿到一个名字,该名字指向导入模块名称空间中的某一地址。
--当一个函数内定义global变量,例如函数前x=1 ,函数中global定义x=2
那么在这个函数没被调用时,x是1。
这个函数被调用后,再调用x就变成了2
from。。。import。。。导入,使用时,不用再加前缀
优点:代码更精简
缺点:容易混淆

3、不推荐 from foo import x, f1, get, change
4、不推荐 from foo import * 非常容易混淆 变量与函数
5、了解: __all__
每个py文件或者模块都有一个内置变量叫__all__,是一个列表,里面记录了本模块或者本文件所有的字符串名字。
from foo import *,,,,这个导入*,也就是导入全部__all__里面的所有名字
控制*代表的名字有哪些
6、起别名
import time as t
from foo import change as c


四、循环导入问题
编写程序,如果两个模块之间交叉互相引用,这是一种非常垃圾的设计,极易瘫痪。
如果实在是有需要,可以利用导入时不执行代码的特点,把交叉引用的东西,放到一个函数内部。
如: def f2():
from foo import f1
。。。
这种解决方案叫做”屎上雕花“



五、搜索模块的路径与优先级
无论是import 还是from ..import ,在导入模块时都涉及到查找问题
优先级:
1、内存(内置模块)
2、按照sys.path中存放的文件的顺序依次查找要导入的模块
import sys
执行print(sys.path)
sys.path的值是一个列表,存放了一系列的文件夹
其中,第一个文件列是当前执行文件所在的文件夹
了解:sys.modules可以查看当前已经加载到内存中的模块
print(sys.modules)可以查看当前加载的模块
了解:
import foo
del foo
此时查看内存中的sys.modules,可以看到foo路径还在内存中,这是python的内存优化机制
为什么没有删除,因为模块是全局的,很可能还会继续使用,或者其他地方还会调用,如果再调用的时候,直接从内存中调用会更加快捷。
首次导入,一定会是从硬盘找。
如果当前文件夹没有,内存也没有,怎么办?
先执行sys.modules.append(r'要导入模块的绝对路径')
然后再执行import 模块名称

六、区别py文件的两种用途
被当作程序运行的时候,运行完后,内存即回收
被当作模块导入时,只有在引用者关闭、del的时候,内存才被回收

被当作程序运行与被当作模块导入的区别。
每个py文件都内置了一个属性叫'__name__'。
当foo被运行时,'__name__'的值为'__main__'
当foo被当做模块导入时,'__name__'的值为”foo“

七、如何编写一个规范的模块
1、如果你的工作是要写一个模块的话,请在第1行加入注释说明,写明本模块的功能与描述
2、再导入其他模块 ,每个导入后面最好也加入描述
3、再定义全局变量,如果不是必须的,最好使用全局变量。后面加注释说明
全局变量的使用要慎重,可能会被别人把值修改掉。最好是都使用局部变量最好。独立性最好,不易被影响。
4、再定义类。 加注释文档说明
5、再定义函数。 函数内要跟上文档注释。
6、if __name__ == '__mail__':
开始主程序



八、包(有__init__的文件夹) 重要
1、什么是包?
包就是一个包含__init__.py文件的文件夹
2、为何要有包?
包的本质是模块的一种形式,包是用来被当做模块导入。
当导包(文件夹)的时候,有一个文件可以代替运行执行(运行包、创建名称空间、导入文件创建变量名称)。
包里面的所有文件功能,都被包含在__init__中。
可以将一个文件夹做成一个模块,导模块就是在导文件夹,就是在导__init__
包的作用就是为了导入,连同下面的文件。不是为了本身运行。
可以把多个文件夹,多个包,都组织到一个文件里面使用。

了解:python3,如果包里面没有__init__,不会出错。python2会出错。
被导入 和 被运行执行 ,是截然不同的两件事。

包可以规范有序的整理模块的功能,包可以把不同的功能放在不同文件分别管理,以升级、管理 、维护提供方便。

3、绝对导入与相对导入
绝对导入:
包的导入,强调三点:
1、站在模块设计者的角度,无论是import,还是from。。import,可以带.
如:from foo.m1 import f1
点的左边,必须是一个包,否则非法
可以带一连串的点,如:import 顶级包.子包.子模块
2、包A 和 包B 有同名模块,导入后也不会有冲突。
如A.a 和 B.a 来自两个名称空间
3、import导入文件时,产生名称空间中的名字来源于文件。
import包,产生的名称空间的名字同样来自于文件。即包下的__init__.py

相对导入: 仅限于包内,不能跨出包。
包内的导入,推荐使用相对导入。
包外的导入,推荐使用绝对导入。
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__))
这条命令会取得当前文件夹的父级目录,并追加到sys.path中。
from core.src import run 然后即可从core包的src模块,导入run函数。



九、软件开发的目录规范
ATM---》 系统文件夹名称
bin 放启动文件
conf 配置文件,放帐号密码文件的 日志文件路径 等
db 数据库相关,对数据库读写操作 ,注册用户 读写表的数据,数据交互
lib 存放程序中常用的自定义模块
core 放最核心代码的逻辑 src.py
api 与外部数据的接口,接口主要用于业务逻辑提供数据操作。
log 存放日志文件
-----上面是包,下面是文件
run.py 程序启动文件,一般放在根目录。因为运行时会默认将运行文件所在的文件夹作为sys.path的第一个路径,这样就省去了处理环境变量的步骤。
setup.py 安装、部署、打包的脚本
requirements.txt 存放软件所需要依赖的外部python包的列表
readme 项目说明文件

代码文件规范
声明‘utf-8’
本模块说明注释
导入其他模块
定义全局变量---越少越好,越少越不容易出问题
定义类
定义函数
if __name__ == __main__
run()

-------------
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__))
这条命令会取得当前文件夹的父级目录,并追加到sys.path中。
from core.src import run 然后即可从core包的src模块,导入run函数。



十、补充函数的知识点
类型提示:type hniting
def register(name: str, age: int, hobbies: tuple):
print(name)
print(age)
print(hobbies)
return ...
python定义函数的时候,变量参数是可以传入任何类型的。想传整数而实际传入字母,浪费时间,有个提示的话,更有效率。
C java 把程序员当驴, python把程序员当人,是会犯错误的
def register(name: str, age: "这里要写数字憨批", hobbies: tuple):
print(name)
print(age)
print(hobbies)
return ...

print(register.__annotations__) # {'name': <class 'str'>, 'age': '这里要写数字憨批', 'hobbies': <class 'tuple'>}


'''

标签:__,文件,规范,导入,模块,import,编写,foo
来源: https://www.cnblogs.com/leeyong49/p/16688808.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有