Python学习笔记-模块概念
1.面对对象编程,初认识
- 面向对象,也就是Python中的类,实际就是个容器,可以把函数和数据都放进去。
- 说白了,就是比函数,更大的容器。
- 那么面对对象,最核心的就是【封装】
2.环境变量是什么?
- 局部变量,全局变量,我们都知道。
- 那么环境变量,我们可以猜一猜,它就是比全局变量,范围更大的变量。
- 官方说法是:
- 环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息
- 我们来看一下windows的环境变量
-
可以看到,上面的都是环境变量。
3.添加到环境变量是什么意思?
- 最常见的添加环境变量,就是把你的程序的路径,像Python里往列表里添加元素一样。
- 把你的程序的路径字符串,添加到path里面,让机器运行的时候,能够找到。
4.软件开发目录规范是对谁而言的?
- 是对开发者而言。方便开发者去对文件的一个管理。
- 对于使用者而言,是不关心你内部层次是否清晰,不关心你的结构是分明。
5.学框架是学什么?
- 也就是学大模块。
6.什么是模块?
- 模块就是一系列功能的集合体
- 换句话说,只要能把一系列功能放到一起的地方,就可以称之为模块。
- 模块大致分为4个种类
- 1. 一个py文件就是一个模块,文件名叫test.py 它的模块叫test
- 2.多个py文件的集合,也就是一个文件夹,就是包。也可以理解为一个大大的模块。(python3的包不需要__init__.py文件)
- (不要求掌握)3.使用C编写并链接到python解释器的内置模块。
- (不要求掌握)4.已被编译为共享库或DLL的C或C++扩展
- 模块的来源有3种:
- 1.自带模块
- 内置在解释器的(用C语言写好的)
- 标准库(用python写好的)
- 2.第三方库模块
- 社区贡献的,用pip install 下载 库&模块&包 (这里叫库,叫模块,叫包,都行)
- 3.自定义模块
- 自己写的
- 1.自带模块
7.为什么要用模块?
- 拿自带模块和第三方模块。是为了图个方便。拿来就用。提升开发效率。
- 为什么用自定义模块?
- 为了自己使用方便,把一些公共的,可以复用的模块提炼出来。作为公共模块,好处是,不用写重复代码,一次修改处处有效。
- 比如,日志模块,就可以作为一个公共模块。
- 高级一点说法是(解决代码冗余的问题)
8.如何使用模块?
- 模块都是被导入使用的,而不是直接运行。
9.run.py首次导入模块spam发什么了什么?
- 1.运行spam.py 并创造了spam的名称空间,把里面的变量放了进去。
- 2.在当前run.py文件产生了spam的变量名,指向spam的名称空间。
-
10.假设run.py 导入多次spam,会执行多次spam里面的代码吗?
-
不会。只有首次执行会运行一次。
11.那么如何引用spam里的变量?
- 指名道姓的去使用。
12. 名称空间的关系是在什么时候确定的?
- 定义阶段。
- 与调用位置没有关系!
- 举例来讲
13. 导入模块规范?
- 通常导入文件放在文件的开头。
- 第一部分:导入自带的模块 (空一行)
- 第二部分:导入第三方的模块 (空一行)
- 第三部分:导入自定义的模块
14.导入模块可以起别名吗?
- 可以。import spamxxxxx as sm 起个别名叫sm
15.import导入和from导入有什么区别?
- 单纯的import导入,每次调用的时候,要指名道姓的去调用。
- 好处:不会有重名的风险
- 缺点:变量名长。
- from导入,一般配合import的使用。
- 好处:使用简洁
- 缺点:有重名的风险
15.1 (温故而知新--再探)import和from区别?
-
import 模块名 模块名.名字 from 模块名 import 名字 名字
- 背后机制是触发了运行模块,产生了模块的名称空间。
16.当涉及多个文件,如何分清变量的值到底是多少?
- 追本溯源,了解最初变量名来自于哪里。
- 以定义阶段为准。
17.当导入多个变量时,怎么使用?
-
from spam import *
- 但是,不是很推荐。
18.__all__是什么?
- 可以控制别人导入的变量名,列表里有的才能导入。
19. 什么是循环导入?
- 类似下面这种。
20. 如何解决循环导入问题?
- 方式1:设计上避免,把导入放到第三方模块。
- 方式2:把import 放到最后。
- 方式3: 定义个函数,把导入语句放里面。
21.模块的搜索顺序是什么?
- 1.内存中已经导入好的。
- 2.内置
- 3.sys.path 环境变量(整个环境都有效)
- 3.5.要执行文件的同级目录(我个人理解要加上这种的,比如要执行main.py 就会搜索它的同级目录)
- 背后原理是,python会自动把要执行的父路径加到sys.path中。
- 如果此时,main.py父路径正好是项目根路径。就很方便。
- 而pycharm除了父目录,会把打开的1.项目 2.标记的根目录. 3.python自动把父目录 这三种都加进来
21.5 python和pycharm的加入sys.path目录有什么区别?
-
python只把执行文件的父目录加入sys.path
-
pycharm会把①父目录,②打开的项目,③标记的根目录 ,三种都加入sys.path
- 这些操作都是他们在背后默默的付出。我真的,哭死~
21.6 (温故而知新)sys.path的第一个是什么?
- 是执行文件的父目录。
22.如何跨文件调用模块?
- 方式1:
-
方式2:
-
23.跨文件调用的核心是?
- 导入目标文件的上层文件夹的绝对路径。
- (如果是基于当前执行文件的位置,就要考虑相当路径。)
- 导入的文件,要跟sys.path里面的路径能接到一起。
-
#方式1: import sys sys.path.append(r"C:\code") import aaa.m2 # 接到一起 C:\code\aaa\m2 print(aaa.m2.f2()) # 方式2: import sys sys.path.append(r"C:\code\aaa") import m2 # 接到一起 C:\code\aaa\m2 m2.f2()
24.import导入的aaa.m2是两个名字吗?
- 不是。
- 是一个名字,是一个整体,不可分割。
- 这个例子中,aaa.m2是一个整体,不是aaa和m2
25.导入自定义的背后的原理是?
- 当导入一个自定义模块时aaa.m1时,系统背后会遍历sys.path里面的路径,逐个把aaa.m1跟sys.path里的路径拼接。
- 如果拼接成功,就会找到。若都没拼接成功,就是失败。
26.软件目录规范(参考)
- bin开始目录
- start.py 入口文件
- config 配置文件 (方便用户定制化)
- setting.py 配置
- core 核心代码的逻辑
- src.py 核心业务的逻辑
- db 数据库
- 存放数据库文件
- lib库(导入的第三方库,以及自定义的库)
- common.py 公共模块
- log日志
- access.log存放日志
- readme 软件说明
27.一个程序其实就是一个文件?
- 对的。
- 主函数入口,就应该是一个。
- 是为了方便我们开发者管理,所以才会有软件目录规范的。
28.一个程序要是有多个入口呢?
- python支持多个入口,或者说是没有限制
29.ATM项目如何写一个装饰器,自动增加函数到字典里?
- 分析需求,需要的是一个前置处理操作。
- 改下模板
-
def outter(n,name): # 传入数据变为n,name 不再是func # @wraps(func) # def index(*args,**kwargs): # 内部参数变为func,???有点疑惑 # 这个里的func就是个参数改为*args也行。 def index(func): #这个func可以改为*args fun_dict[str(n)] = [name,func] #这里也要同步改为*args,注意不能少* # res = func(*args,**kwargs) 不需要执行, # return res return index
- 全部代码
-
1 fun_dict = {} 2 def outter(n, name): # 传入数据变为n,name 不再是func 3 # @wraps(func) 4 # def index(*args,**kwargs): # 内部参数变为func,???有点疑惑 5 def index(func): 6 fun_dict[str(n)] = [name, func] 7 # res = func(*args,**kwargs) 不需要执行, 8 # return res 9 return index 10 # # 需求加个装饰器 (第一次写) 11 # def outter(n, name): 12 # def inner(func): 13 # fun_dict[str(n)] = [name, func] 14 # # 相当于一个前处理的装饰器 15 # 16 # return inner 17 18 19 @outter(1, "提现") 20 def withdraw(name): 21 print(name) 22 print("提现功能") 23 24 25 @outter(2, "转账") 26 def transfer(): 27 print("转账功能") 28 29 30 @outter(3, "查询余额") 31 def check_balance(): 32 print("查询余额") 33 34 35 print(fun_dict) 36 # func_dict = { 37 # "1":["提现",withdraw], 38 # "2":["转账",withdraw], 39 # "3":["查询余额",withdraw], 40 # } 41 # fun_dict["1"][-1](123)
30.导入文件路径怎么操作的?
-
import os import sys # print(__file__) # 本文件的路径 # os.path.dirname(__file__) # 本文件的路径的上一层 # print(os.path.dirname(os.path.dirname(__file__))) # 上上层 BASE_PATH = os.path.dirname(os.path.dirname(__file__)) sys.path.append(BASE_PATH) print(sys.path)
31.sys.path导入路径的方式?
-
project_path = os.path.abspath(os.path.join(os.getcwd(), "../../../")) # ..test_robot/ project_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) # 另外一种写法 print(project_path)
32.导入路径有什么讲究吗?
-
sys.path是使用任何场景的。
-
在pycharm里,可以用标记位根目录,来添加路径。
- 适用于本地调试,分支自调试。
- 不适用于,多入口的情景,(例如case/H100/H200)
-
(扩展)执行python main.py发生了什么?
- python会自动找到main.py的同级目录。
- 所以,有些Python开发者,会把main.py放在项目 首页 顶层目录下,图一个导入模块方便。
33.导入语句的.和使用的.一样吗?
- 不一样。
- 导入语句的点(.)是路径分割符(/)
- 使用的点(.)是属性的意思
34.py文件即可以执行使用,又可以导入使用?
- 是的
35.一个文件被导入使用和执行使用,有什么变化?
- __name__不同。
- 比如一个spam.py 执行使用的时候,__name__ == "__main__"
- 当这个spam.py 被导入使用的时候,__name__ == "spam"
36.__name__=="main"也用于主函数入口?
- 是的
- 有时候,主函数,没有被导入的需求,也会写一个。习惯使然~
37.包内部的导入应该使用相对导入?
- 是的。
- 可以参考常见的json的导入模式
-
38.init文件的作用是啥?
39.导入模块aaa,就是导入它的init文件
- init文件里的变量都会导入进来。
- 把握这个原理就行。
- 注意内部导入用点(.)