Loading

循环导入问题,判断文件类型 ,模块的查找顺序(重要) ,绝对导入与相对导入 ,模块与包(简单), 软件开发目录规范

模块

我们基本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。
为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。
'''
模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能
'''

什么是模块?

模块就是一系列功能的结合体,可以直接使用

为什么要用模块?

极大地提升开发效率(“拿来吧你”)

模块的三种来源

1.内置的模块
	python解释器自带的,直接导入使用即可
2.自定义模块
  自己写的代码,封装成模块,自己用或者发布到网上供别人使用
3.第三方模块
  别人写的发布到网上的,可以下载使用的模块(很多牛逼的模块)

模块的四种表现形式

1.使用python代码编写的py文件  # 掌握
2.多个py文件组成的文件夹(包)  # 掌握
3.已被编译为共享库或DLL的C或C++扩展
4.使用C编写并链接到python解释器的内置模块
# 使用注意事项:
在研究模块的时候,一定要分清楚谁是执行文件,谁是被导入文件(模块)
导入模块内部发生的事情:
    1.执行当前文件,产生一个当前文件的名称空间
    2.执行import句式,导入模块文件(即执行模块文件代码产生模块文件的名称空间)
    3.在当前文件的名称空间中产生一个模块的名字,指向模块的名称空间
    4.通过该名字就可以使用到模块名称空间中的所有数据
注:
    相同的模块反复被导入只会执行一次
    improt md	有效
    improt md	无效
    improt md	无效

import...句式

import + 模块名字
import句式的特点:
    可以通过import后面的模块名点的方式,使用模块中所有的名字,并且不会与当前名称空间中的名字冲突

from...import...句式

form 模块名 import 模块里的变量名\函数名,可以是多个,用逗号隔开
# 注意事项:
'''
1.执行当前文件产生一个名称空间
2.执行导入语句,运行模块文件产生名称空间存放运行过程中的所有名字
3.将import后面的名字直接拿到当前执行文件中
'''
"""
1.重复导入也只会导入一次
2.使用模块名称空间中的名字不需要加模块名前缀,直接使用即可
3.from...import的句式会产生名字冲突的问题
4.使用from...import的句式,只能使用import后面出现的名字
	from...import...可以简单的翻译成中文
	从...里面拿...来用,没有提到的都不能用,指名道姓
"""

导入补充

给模块重新取名(使用较多)

eg:
    import 模块名 as 新名字
    
"""
import md as new_md
"""

连续导入多个模块或者变量名

import 模块1,模块2,模块3
from 模块名 import 变量名1,变量名2,变量名3

'''
连续导入多个模块,这多个模块最好有相似的功能部分,如果没有建议分开带入

如果是同一模块下的多个变量名就没啥问题
'''

通用导入

from 模块名 import *
'''
*表示模块里面所有的名字,from...import的句式也可以导入所有的名字
如果模块文件中使用了__all__限制可以使用的名字,那么*号就只能使用__all__后面列举的名字
'''
eg:
    __all__ = ['name','pwd']

循环导入问题

循环导入就是两个文件彼此导入彼此
循环导入的时候极有可能出现某个名字还没有被创建就使用的情况导致报错
'''
如果出现了循环导入的问题,那么一定是你的程序设计的不合理,尽量避免循环导入,
'''
# 错误示范:
import md1
name = 'from md'
print(md1.name)
##############
import md
name = 'from md1'
print(md.name)

# AttributeError: module 'md1' has no attribute 'name'
解决循环导入问题的方式:
# 方式1:将循环导入的句式写在变量名或文件的最下方
    name = 'from md'
    import md1
    print(md1.name)
# 方式2:函数内导入模块
    def index():
    import md1
    print(md1.index())
index()

判断文件类型

py文件可分为两种类型
1.执行文件
2.被导入文件
有一个内置变量__name__:
当__name__所在的文件是执行文件的时候,结果是__main__
当__name__所在的文件是被导入文件时候,结果是文件名(模块名)
eg:
    import b  # b  (被导入文件,返回结果是文件名b)
    print(__name__)  # __main__ (执行文件,返回结果是__main__)
可以借助与__name__区分被导入的代码和测试代码
if __name__ == '__main__':
	当前文件是执行文件的时候才会执行的子代码快
"""
在pychorm中可以直接输入main之后按tab键,if __name__ == '__main__':这句代码就直接出来了
"""

模块的查找顺序

'''
1.先从内存空间中查找
2.再从内置模块中查找
3.最后去sys.path查找(类似于环境变量)
如果上面三个地方都没找到,那么就直接报错
'''
'''在创建py文件时候一定不要跟模块名(内置\第三方)冲突!!!'''
1.验证先从内存空间中查找
程序运行时,会把文件从外存中读取到内存
import md1
import time
time.sleep(15)  # 睡眠期间将md1文件删除
print(md1.name)
2.验证再从内置模块中查找
import time
print(time)
print(time.time())
3.验证sys.path查找
import sys
print(sys.path)
# ['E:\\Pythonexercise\\day18',
# 'E:\\Pythonexercise\\day18',
# 'F:\\pycharm\\PyCharm 2021.1.1\\plugins\\python\\helpers\\pycharm_display',
# 'F:\\python36\\python36.zip'
...
# sys.path中虽然有很多路径 但是只需要重点关注第一个
第一个就是执行文件所在的路径
查找模块的时候只需要站在执行文件所在的路径查看即可
解决方法
# 方式1:主动添加sys.path路径(类似于添加环境变量)
import sys
sys.path.append(r'E:\Pythonexercise\day18\a')
import a
print(b.name)
'''
pychorm可能会飘黄或者飘红线,但代码本身没有任何问题
'''
# 方式2:利用from...import...句式指名道姓的查找
from a import b  # 从文件夹a中导入b.py文件(模块)
print(b.name)

绝对导入与相当导入

1.在导入模块的时候一切查找模块的句式都是以执行文件为准
	无论导入的句式实在执行文件中还是在被导入文件中
    
# 绝对导入
永远按照执行文件所在的路径一层一层往下查找(简单粗暴好用)
	from a import md
# 相对导入
相当导入打破了必须参照执行文件的所在路径的要求 只需要考虑当前模块所在的路径然后使用特殊符号.去查找其他模块即可
from . import md
from .. improt md
from ../.. import md
相对导入只能给用于被导入文件,不能用在执行文件中
'''
.便是当前路径
..表示上一层路径
../..表示上上一层路径
'''

'''简单来说,包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空。__init__.py 用于标识当前文件夹是一个包。'''

# 本质就是文件夹里面有一个__init__.py文件

# 用实际生活来比喻:
包就是多个模块的结合体(内部存放了多个模块文件)
  	eg:我们的电脑某个文件夹下面有很多不同类型的文件
      	视频文件、音频文件、文本文件、图片文件
       为了方便管理我们会习惯性的创建不同的文件夹分类管理
      	学习视频
          J老师视频合集
          R老师视频合集
          C老师视频合集
        学习笔记
        	D老师经典语录
          	A老师经典语录
        ...
'''
在导入包的时候,索要名字是跟包里面的__init__.py文件要
1.如果想直接通过包的名字使用包里面所有的模块,那么需要在__init__.py中提前导入
eg:
	import aaa,bbb,...(在__init__.py文件里面写)
2.可以直接忽略掉__init__的存在,使用绝对导入的方式也可以
不用考虑包的存在,直接当成普通的文件夹
eg:
	from exec.aaa import index
'''
包里面__init__可以看作是模块的集合体,可以使用它来调用所有的模块,也可以跳过他自己来调用

软件开发目录规范

我们实际工作中编写的程序软件都是有很多文件夹和文件组成的

这些文件夹和文件都有各自存在的意义和主要功能

查看文件名称可以找到相同文件名的文件

1.bin文件夹
	存放程序的启动文件    start.py
2.conf文件夹
	存放程序的配置文件	settings.py
3.core文件夹
	存放程序的核心业务	src.py
    就是最为重要的代码能够实现具体需求
4.lib文件夹
	存放程序公共的功能	common.py
5.db文件夹
	存放程序的数据		userinfo.txt
6.log文件夹	
	存放程序的日志记录	log.log
7.readme文本文件
	存放程序的说明、广告等额外信息
8.requirements.txt文本文件
	存放程序需要使用的第三方模块及对应的版本
    
    

posted @ 2022-03-25 19:58  香菜根  阅读(32)  评论(0编辑  收藏  举报