文章目录
一、py文件
1.1 一个py文件的几种用途, 执行py文件和导入py文件的区别是什么
- 当成程序: 右键运行run发生了什么, 跟名称空间相关的
- 当模块运行的时候
# m.py
print('模块m')
def f1():
print()
# run.py
import m
print(111)
print(222)
x = 1
y = 2
1.2 import 和 from import
- import导入时模块在使用时必须加前缀"模块."
- 优点: 肯定不会与当前名称空间的名字发生冲突
- 缺点:加前缀显得麻烦
- form … import … 导入也发生了三件事
- 产生一个模块得名称空间
- 运行foo.py将运行过程中产生得名字都丢到模块得名称空间去
- 在当前名称空间拿到一个名字,改名字等于模块名称空间得某一个内存地址
# 第一种写法
from foo import x
from foo import get
# 第二种写法(不推荐)
from foo import x, get
# 第三种写法 (很少用,其实调用得是foo中得__all__控制*代表得名字)
from foo import *
- 循环导入问题(模块间的互相调用,不要这么写,如果遇到见博客)
1.3 模块的搜索路径与优先级
- 无论是import还是from … import 再导入包的时候都涉及到查找问题
- 优先级
- 内存:(内置模块)
- 硬盘: 按照sys.path中存放的文件的顺序依次查找要导入的模块
import sys
# 1. 值为一个列表, 存放一系列的文件夹
# 其中第一个文件夹是当前文件所在的文件夹
# 第二个是pycharm加的,一般不考虑,这个就是在硬盘查找的顺序
print(sys.path)
# 2. 验证是先在内存中查找
import foo # 内存中已经有foo
foo.say()
import time
time.sleep(10) # 在这10s删除foo.py
import foo
foo.say() # 依旧执行,说明是内存中的foo
#3. sys.modules查看已经在内存中的模块
import sys
import foo
print(sys.modules) # foo在
del foo
print(sys.modules) # foo还在
# 这是python的设计机制, 申请一块内存定义模块相对较难,所以不删除
# 4. 如何将文件夹添加到环境变量中
import sys
sys.path.append(r'路径') # 在硬盘位置都没找到的时候,会找这里
print(sys.modules)
1.4编写一个规范的模块
"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.5函数补充
- Python是一门解释型的强类型动态语言
- 针对动态语言
# 没有强制要求定义变量的类型
def register(name: str, age: int) -> tuple:
print(name)
print(age)
return (1, 2)
print(register('zpp', 'age'))
# : 后面就是注释, 不影响程序的执行, 类似于给一个默认值
def register(name: str = 'zpp', age: int = 12) -> tuple:
if isinstance(name, str) and isinstance(age, int):
print(name)
print(age)
return (1, 2)
else:
print("name is str, age is int")
print(register('zpp', '18'))
# 查看注释内容
print(register.__annotations__)
二、包
pool/ #顶级包
├── __init__.py
├── futures #子包
│ ├── __init__.py
│ ├── process.py
│ └── thread.py
└── versions.py #子模块
- 包就是一个包含__init__.py文件的文件夹
- 为何要有包
- 包的本质是模块, 模块的一种形式, 包是用来被当作模块导入
# 1. 产生一个名称空间
# 2. 运行包下的__init__.py文件, 蒋运行过程中产生的名字都丢到1的名称空间中
# 3. 在当前执行文件的名称空间中拿到他的名字, 名字指向1的名称空间
2.1 绝对导入
import foo
import sys
# 如何将分散到包中的文件.py中的函数导入到运行文件中
# 方法一:绝对导入,以包的文件夹作为起始来进行导入
from foo.m import f1
print(sys.path)
f1()
# 知道以后可以将__init__.py中加上, 模块的制作者
from foo.m import f1
from foo.m import *
# 使用者也可以
from foo import f1
f1()
2.2 相对导入
# 方法二: 相对导入, 只能在包内使用,不能超出包内
# .代表当前文件夹, ..代表上一层文件夹
from .m1 import f1
from .m2 import f2
from .bbb.m3 import f3
# 在m3中
from ..m1 import f1
from ....foo import f4
2.3 强调3点
1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
2、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间
3、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
三、软件开发的目录规范
ATM/
|-- 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: 项目说明文件。
- 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]: https://www.bilibili.com/video/BV1QE41147hU?p=17
[2]: https://www.zhihu.com/column/c_1189883314197168128