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.自定义模块
      • 自己写的  

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)
    View Code

     

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文件里的变量都会导入进来。
  • 把握这个原理就行。
  • 注意内部导入用点(.)

  

 

 

 

 

参考资料

林海峰

posted @ 2022-12-26 23:06  o蹲蹲o  阅读(51)  评论(0编辑  收藏  举报