python——模块介绍

目录

一、什么是模块

模块就是一系列功能的集合体

二、模块四种通用的类别

1、 一个python文件就是一个模块,文件名为test.py,模块名为:test
2、盛放有多个py文件的文件夹也是一个功能的集合体,也就是一种模块,相当于一种超级模块,称之为:包
3、已被编译为共享库或DLL的C或C++扩展
4、使用C编写并链接到python解释器的内置模块

三、模块三种来源

1、自带的模块: 内置模块、标准库
print(type(print))
2、第三方模块
pip3 install requests

import time
print(type(time))
3、自定义的模块: 一个python文件就是一个模块,文件名为test.py,模块名为:test

四、为何要用模块

1、内置以及第三方模块: 拿来主义,提升效率
2、自定义模块:可以将程序的各个部分功能提取出来 放到一个模块中 供大家使用
好处是:减少代码冗余,程序组织结构更加清晰

五、如何用模块

1、首次导入模块会发生3件事

1、执行spam.py
2、产生spam.py的名称空间,将spam.py运行过程中产生的名字都丢到spam的名称空间中
3、在当前文件中产生一个名字spam,该名字指向2中产生的名称空间
print('from the spam.py')

money = 1000
def read1():
    print('spam模块', money)
def read2():
    print('spam模块')
def change():
    global  money           # global修改全局变量
    money=0

2、使用模块之import

import导入模块在使用时必须加前缀 “模块."如:spam.
优点:肯定不会与当前名称空间中的名字冲突
缺点:加前缀显得麻烦
#模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句),如下 

#test.py
import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
import spam
import spam
import spam

'''
执行结果:
from the spam.py
'''

3、被导入的模块有独立的名称空间

测试一:money与spam.money不冲突
#test.py
import spam 
money=10
print(spam.money)

'''
执行结果:
from the spam.py
1000
'''
测试二:read1与spam.read1不冲突
#test.py
import spam
def read1():
    print('========')
spam.read1()

'''
执行结果:
from the spam.py
spam模块 1000
'''
测试三:执行spam.change()操作的全局变量money仍然是spam中的
#test.py
import spam
money=1
spam.change()
print(money)

'''
执行结果:
from the spam.py
1
'''

4、可以以逗号为分隔符在一行导入多个模块

# 不建议在同一行导入多个模块
import spam,foo,time

# 建议分开导入,如下:
import spam
import foo
import time


5、from...import...导入模块

优点:无需加前缀,代码更为简洁
缺点:容易与当前名称空间中的名字冲突
From...import...发生的三件事情
1、执行spam.py文件
2、会触发模块文件的运行,产生一个模块的名称空间,将运行模块文件过程中产生的名字都丢到模块的名称空间
3、在当前名称空间中产生一个名字如:money,该名字指向模块的名称空间中的那个money
from...import...使用
from spam import money
from spam import read1
from spam import read2
from spam import change
案例:Run.py
from spam import money
from spam import read1
from spam import read2
from spam import change

money = 20000  # 与spam.py重名时,会以当前文件定义为准
print(money)   # 输出:20000

print(read1)
print(read2)
print(change)

read1()    # 输出:1000
def read1():   # 与spam.py重名时,会以当前文件定义为准
    print(money)    # 输出:20000
read1()

Spam.py
print('from the spam.py')

money = 1000
def read1():
    print('spam模块', money)
def read2():
    print('spam模块')
def change():
    global  money           # global修改全局变量
    money=0

from...import*(大多数不建议使用)

*导入模块中所有的名字
# 可以在spam.py文件中写入:
# __all__ = ["money","read1"]
# __all__控制被导入文件的*导入的具体个数

# run.py
from spam import *
起别名
from spam import money as m,read1 as f
print(m)
f()

六、模块循环导入问题案例

WechatIMG132

分析

问题主要出在,模块导入一遍后,加载名称空间,会运行模块的代码,最后在当前位置拿到名字,如果第二次导入,就直接不用运行前两部,直接拿到名字,所以循环导入第二次就会产生致命的问题。

先执行run.py,造名称空间并运行代码
---->执行import m1,开始导入m1并运行其内部代码--->打印内容"正在导入m1"
--->执行from m2 import y 开始导入m2并运行其内部代码--->打印内容“正在导入m2”
--->执行from m1 import x,由于m1已经被导入过了,所以不会重新导入,所以直接去m1中拿x,然而x此时并没有存在于m1中,所以报错

解决方式一:直接把名字提上来

image-20201210173233397

解决方式二:导入语句放到函数中

WechatIMG133

利用函数定义阶段不会运行的特点

七、py文件区分两种用途:模块与脚本

编写好的一个python文件可以有两种用途:

一:脚本,一个文件就是整个程序,用来被执行
二:模块,文件中存放着一堆功能,用来被导入使用

区别:

1、作为脚本运行,直接右键运行该pytohn文件
2、作为模块,被import导入到其他文件中
python为我们内置了全局变量__name__:
当文件被当做脚本执行时:name 等于'main'
当文件被当做模块导入时:__name__等于模块名
作用:用来控制.py文件在不同的应用场景下执行不同的逻辑

​ if name == 'main':

案例

run.py

import m1 #无需再跑到run.py执行

m1.py

def f1():
    print('from f1')

def f2():
    print('from f2')

if __name__ == '__main__':     # 把当前文件当成导入文件,直接执行pytohn.m1.py
    f1()
    f2()

八、模块搜索路径优先级

无论是import还是from...import,在导入模块时,都涉及查找问题
模块的查找顺序
  • 内存

  • 内置模块

  • 硬盘:按照sys.path中存放的文件顺序依次查找要导入的模块

    import sys
    值为一个列表,存放了一系列的对文件夹
    其中一个文件夹是在当前执行文件所在在的文件夹
    print(sys.path)
    
    import m1  # 内存中已经有m1
    
    import time
    time.sleep(10)
    
    import m1
    m1.f1()
    
了解
# sys.modules查看已经加载到内存的模块

import sys
import foo  # foo = 模块的内存地址
del foo

print(sys.modules)

# sys.path.append()  添加文件到环境变量
import sys
sys.path.append('/Users/yueying/PycharmProjects/16期新/day14/模块from')

import m1


m1.f1()
posted @ 2020-12-09 17:49  岳岳-  阅读(53)  评论(0编辑  收藏  举报