14天 模块 , 导模块 , 循环导入, 相对,绝对导入, 项目目录规范,

模块

模块:一系列功能的集合体

模块的三种来源:

1.内置的

2.自定义的

3.第三方的

四种表现形式:

  1 使用python编写的.py文件(一个py.文件也可以称之为一个模块)

  2 已被编译为共享库或DLL的C或C++扩展

  3 把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)

  4 使用C编写并链接到python解释器的内置模块

包:一系列py.文件的结合体.

为什么用模块:

1.用别人写好的模块(内置的,第三方的):典型的拿来主义,极大地提高开发效率.

2.使用自己写的模块(自定义):当程序大,多文件都需要相同的方法时,可以将公共的方法都写在一个py.文件中,当做模块导入

解耦合

区分执行文件和被导入文件

import导入模块

md.py

print('from the md.py')
money = 1000
def read1():
  print('md',money)
def read2():
  print('md模块')
  read1()
def change():
  global money
  money = 0
View Code

run.py

import md
View Code

右键运行run.py文件首先会创建一个run.py的名称空间
首次导入模块(md.py)
1.执行md.py文件
2.运行md.py文件中的代码将产生的名字与值存放到md.py名称空间中.
3.在执行文件中产生一个执行名称空间的名字(md)


多次导入不会再执行模块文件,会沿用第一次导入的结果

访问模块中的名字指向的值
print(md.money)
#得到了值
模块名.名字
print(md.read1)
print(md.read2)
print(md.change)
#均得到了函数的地址
View Code
import md
money = 9999
print(money)
#得到了当前执行文件的值
def read1():
    print('from run read1')
read1()
#得到当前文件的值
View Code

1.只要你能拿到函数名 无论在哪都可以通过函数加括号来调用这个函数(会回到函数定义阶段 依次执行代码)
2.函数在定义阶段 名字查找就已经固定了 不会因为调用位置的变化而改变

使用import导入模块,访问模块名称空间中的名字统一句式:模块名.名字
    1.指名道姓的访问模块中的名字 永远不会与执行文件中的名字冲突
    2.你如果想访问模块中名字 必须用模块名.名字的方式

import os,sys
当几个模块有相同部分或者属于用一个模块,可以使用上面的方法,一行导入多个模块
当几个模块没有联系的情况下 应该分多次导入
import os
import time
import md
ps:通常导入模块的句式会写在文件的开头

取别名

import aaaaaaaaaa.py as a
当模块名字比较复杂的情况下 可以给该模块名取别名
View Code

异常

while True:
    try:
        print(d.__next__())
        print(name)
        sdfsdfj
    except Exception:
        break
name = "bobob"
异常有两大类
    1.语法结构错误:需要你当场修改 异常捕获没法完成
    2.逻辑错误:异常捕获可以处理
View Code
from...import...模块导入
md1.py
print('from the md1.py')
money = 1000
def read1():
  print('md',money)
def read2():
  print('md模块')
  read1()
def change():
  global money
  money = 0
__all__ = ['money','read1','read2']
View Code

run1.py

from md1 import money,read1,read2,change
View Code

会先创建run1.py的名称空间
首次导入md1.py模块
1.运行md1.py
2.将产生的名字存放到md1.py名称空间中
3.直接拿到指向模块md1.py名称空间中某个值的名字

导入完成的三件事

1.
将被导入的模块编译形成对应的pyc文件

2.
进入模块,从上执行执行模块中的代码,将产生的所有名字存放在该模块文件的全局名称空间中

3.
在导入模块的文件中形成(一个或多个)
名字指向模块全局名称空间中的(一个或多个)
具体名字

from 模块名 import 模块中的名字1,

..., 模块中的名字n

from 模块名 import 名字 as 别名

from ...import导入依赖环境变量 sys.path
View Code

利用from...import...句式
缺点:
1.访问模块中的名字不需要加模块名前缀
2.在访问模块中的名字可能会与当前执行文件中的名字冲突
优点
1.省略了点语法 2.指名道姓可读性强 3.可以起别名解决冲突

from md1 import * 
  # 一次性将md1模块中的名字全部加载过来
  模块中默认会添加 __all__ ,__all__ 就是管理模块中能被 * 导入的变量们

 __all__可以自定义,自定义 * 能导入的变量们, __all__的list中名字全部可以自定义

 系统默认添加的__all__中不会纳入 __开头的名字

       -- 所以默认在外界通过from...import *无法导入_开头的名字

-- _开头的名字对from...import *是隐藏的,指名道姓依然可以被外界导入使用
__all__可以指定当所在py文件被当做模块导入的时候
可以限制导入者能够拿到的名字个数
循环导入问题
t1.py
import m1
m1.f1()
View Code

m1.py

print('正在导入m1')
from m2 import y  # 首次导入m2

x = 'm1'
View Code

m2.py

print('正在导入m2')
 from m1 import x  # 第二次导m3
y = 'm2'
View Code
打印结果
    正在导入m1
    正在导入m2

如果出现循环导入问题 那么一定是你的程序设计的不合理
循环导入问题应该在程序设计阶段就应该避免

解决循环导入问题的方式
    1.方式1
        将循环导入的句式写在文件最下方()
    
    2.方式2
        函数内导入模块

解决: 

m1.py

方式1
print('正在导入m1')
x = 'm1'
from m2 import y  # 首次导入m2


print('正在导入m1')
def f1():
  from dir1.dir.m2 import y,f2
  print('m1.f1>>>y:',y)
  f2()
x = 'm1'
View Code

m2.py

方式1
print('正在导入m2')
y = 'm2'
from m1 import x  # 第二次导m

print('正在导入m2')
def f2():
  from dir1.dir.m1 import x
  print('m2.f2>>>x:',x)
y = 'm2'
View Code
链式导入问题

t1.py

import m1

m1.f1()
View Code

m1.py

print('正在导入m1')
from m2 import y  # 首次导入m2
x = 'm1'
View Code

m2.py

print('正在导入m2')
y = 'm2'
View Code
t1导入m1,m1导入m2,m2导入m3

 执行流程:右键执行t1,在t1导入m1模块的地方直接进入m1,去执行m1,同理在m1执行过程中遇到导入m2,会马上进入m2,去执行m2,一直到m3,m3执行完毕,会回到m2中导入m3的语句,接着往下执行m2,m2执行完毕回到m1,以此类推返回到t1

 在整个执行流程中,遇到任何模块的二次导入,都是直接引用内存中的名称空间,不会再次进入模块

  

__name__

def index1():
    print('index1')

def index2():
    print('index2')


print(__name__)
区分执行文件和被导入文件
# 当文件被当做执行文件执行的时候__name__打印的结果是__main__
# 当文件被当做模块导入的时候__name__打印的结果是模块名(没有后缀)
if __name__ == '__main__':
    index1()
    index2()


if __name__ == '__main__':  # 快捷写法 main直接tab键即可
    index1()
    index2()

  

模块的查找顺序
1.先从内存中找
2.内置中找
3.sys.path中找(环境变量):
内置(built-in):
自定义(系统提供|第三方提供|自定义)

加载顺序:
内置>sys.path(安装环境变量中路径的先后顺序逐一加载)

  

import sys
print(sys)
是一个大列表,里面放了一对文件路径,第一个路径永远是执行文件所在的文件夹
注意py文件名不应该与模块名(内置的,第三方)冲突

 

相对导入
.代表的当前路径
..代表的上一级路径
...代表的是上上一级路径

注意相对导入不能在执行文件中使用
相对导入只能在被导入的模块中使用,使用相对导入 就不需要考虑
执行文件到底是谁 只需要知道模块与模块之间路径关系
View Code
绝对导入
绝对导入必须依据执行文件所在的文件夹路径为准
    1.绝对导入无论在执行文件中还是被导入文件都适用

 

环境配置

 

环境变量:存放路径的list

sys.path就是环境变量

默认为当前执行文件所在的路径

清空环境变量:所有导入都不能使用

sys.path.clear()

添加指定路径到环境变量

sys.path.append()

sys.path.insert()

 如;

import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
if __name__ == '__main__':
    src.run()
View Code
项目目录规范
bin
    start.py	启动文件
conf
    settings.py		配置文件
core
    src.py		核心代码文件
lib
    common.py	公共文件
db
	数据文件
log
	logging 	日志记录文件
readme		项目说明简介

  

 









原文地址:https://www.cnblogs.com/komorebi/p/11197260.html